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

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

parent 42eb52c4
*.pyc
*.so
\ No newline at end of file
obj-m = cp210x.o
KVERSION = $(shell uname -r)
all:
make -C /lib/modules/$(KVERSION)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(KVERSION)/build M=$(PWD) clean
This diff is collapsed.
......@@ -5,8 +5,19 @@
# Licence: GPL v2 or later.
# Website: http://www.ohwr.org
sudo rmmod cp210x
sudo rmmod usbtmc
sudo rmmod spec
sudo insmod ./test/fmcdelay1ns4cha/lib/spec/kernel/spec.ko
sudo insmod ./cp210x-driver/cp210x.ko
cd usbdriver
sudo ./usbtmc_load
cd ..
LOGDIR=./log_fmcdelay1ns4cha
mkdir -p $LOGDIR
sudo rm -fr $LOGDIR/pts*
......@@ -41,7 +52,7 @@ do
echo "Test series run $nb_test out of $nb_test_limit"
echo " "
sudo ./ptsDelay.py -b FmcDelay1ns4cha -s $serial -e $extra_serial -t./test/fmcdelay1ns4cha/python -l $LOGDIR 00 01 02 03 04 05
sudo ./ptsDelay.py -b FmcDelay1ns4cha -s $serial -e $extra_serial -t./test/fmcdelay1ns4cha/python -l $LOGDIR 00 01 02 03 04 05 06
if [ "$nb_test" != "$nb_test_limit" ]
then
......
No preview for this file type
#ifndef __ACAM_GPX_H
#define __ACAM_GPX_H
#define AR0_ROsc (1<<0)
#define AR0_RiseEn0 (1<<1)
#define AR0_FallEn0 (1<<2)
#define AR0_RiseEn1 (1<<3)
#define AR0_FallEn1 (1<<4)
#define AR0_RiseEn2 (1<<5)
#define AR0_FallEn2 (1<<6)
#define AR0_HQSel (1<<7)
#define AR0_TRiseEn(port) (1<<(10+port))
#define AR0_TFallEn(port) (1<<(19+port))
#define AR1_Adj(chan, value) (((value) & 0xf) << (chan * 4))
#define AR2_GMode (1<<0)
#define AR2_IMode (1<<1)
#define AR2_RMode (1<<2)
#define AR2_Disable(chan) (1<<(3+chan))
#define AR2_Adj(chan, value) (((value)&0xf)<<(12+4*(chan-7)))
#define AR3_RaSpeed(num,val) (val << (num*2 + 21))
#define AR3_Zero (0) // nothing interesting for the Fine Delay
#define AR4_StartTimer(value) ((value) & 0xff)
#define AR4_Quiet (1<<8)
#define AR4_MMode (1<<9)
#define AR4_MasterReset (1<<22)
#define AR4_PartialReset (1<<23)
#define AR4_AluTrigSoft (1<<24)
#define AR4_EFlagHiZN (1<<25)
#define AR4_MTimerStart (1<<26)
#define AR4_MTimerStop (1<<27)
#define AR5_StartOff1(value) ((value)&0x3ffff)
#define AR5_StopDisStart (1<<21)
#define AR5_StartDisStart (1<<22)
#define AR5_MasterAluTrig (1<<23)
#define AR5_PartialAluTrig (1<<24)
#define AR5_MasterOenTrig (1<<25)
#define AR5_PartialOenTrig (1<<26)
#define AR5_StartRetrig (1<<27)
#define AR6_Fill(value) ((value)&0xff)
#define AR6_StartOff2(value) (((value)&0x3ffff)<<8)
#define AR6_InSelECL (1<<26)
#define AR6_PowerOnECL (1<<27)
#define AR7_HSDiv(value) ((value)&0xff)
#define AR7_RefClkDiv(value) (((value)&0x7)<<8)
#define AR7_ResAdj (1<<11)
#define AR7_NegPhase (1<<12)
#define AR7_Track (1<<13)
#define AR7_MTimer(value) (((value) & 0x1ff)<<15)
#define AR14_16BitMode (1<<4)
#define AR8I_IFIFO1(reg) ((reg) & 0x1ffff)
#define AR8I_Slope1(reg) ((reg) & (1<<17) ? 1 : 0)
#define AR8I_StartN1(reg) (((reg) >> 18) & 0xff)
#define AR8I_ChaCode1(reg) (((reg) >> 26) & 0x3)
#define AR9I_IFIFO2(reg) ((reg) & 0x1ffff)
#define AR9I_Slope2(reg) ((reg) & (1<<17) ? 1 : 0)
#define AR9I_StartN2(reg) (((reg) >> 18) & 0xff)
#define AR9I_ChaCode2(reg) (((reg) >> 26) & 0x3)
#define AR8R_IFIFO1(reg) ((reg) & 0x3fffff)
#define AR9R_IFIFO2(reg) ((reg) & 0x3fffff)
#define AR11_StopCounter0(num) ((num) & 0xff)
#define AR11_StopCounter1(num) (((num) & 0xff) << 8)
#define AR11_HFifoErrU(num) (1 << (num+16))
#define AR11_IFifoErrU(num) (1 << (num+24))
#define AR11_NotLockErrU (1 << 26)
#define AR12_HFifoE (1<<11)
#define AR12_NotLocked (1<<10)
#endif
#ifndef __ACAM_GPX_H
#define __ACAM_GPX_H
#define AR0_ROsc (1<<0)
#define AR0_RiseEn0 (1<<1)
#define AR0_FallEn0 (1<<2)
#define AR0_RiseEn1 (1<<3)
#define AR0_FallEn1 (1<<4)
#define AR0_RiseEn2 (1<<5)
#define AR0_FallEn2 (1<<6)
#define AR0_HQSel (1<<7)
#define AR0_TRiseEn(port) (1<<(10+port))
#define AR0_TFallEn(port) (1<<(19+port))
#define AR1_Adj(chan, value) (((value) & 0xf) << (chan * 4))
#define AR2_GMode (1<<0)
#define AR2_IMode (1<<1)
#define AR2_RMode (1<<2)
#define AR2_Disable(chan) (1<<(3+chan))
#define AR2_Adj(chan, value) (((value)&0xf)<<(12+4*(chan-7)))
#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 AR4_StartTimer(value) ((value) & 0xff)
#define AR4_Quiet (1<<8)
#define AR4_MMode (1<<9)
#define AR4_MasterReset (1<<22)
#define AR4_PartialReset (1<<23)
#define AR4_AluTrigSoft (1<<24)
#define AR4_EFlagHiZN (1<<25)
#define AR4_MTimerStart (1<<26)
#define AR4_MTimerStop (1<<27)
#define AR5_StartOff1(value) ((value)&0x3ffff)
#define AR5_StopDisStart (1<<21)
#define AR5_StartDisStart (1<<22)
#define AR5_MasterAluTrig (1<<23)
#define AR5_PartialAluTrig (1<<24)
#define AR5_MasterOenTrig (1<<25)
#define AR5_PartialOenTrig (1<<26)
#define AR5_StartRetrig (1<<27)
#define AR6_Fill(value) ((value)&0xff)
#define AR6_StartOff2(value) (((value)&0x3ffff)<<8)
#define AR6_InSelECL (1<<26)
#define AR6_PowerOnECL (1<<27)
#define AR7_HSDiv(value) ((value)&0xff)
#define AR7_RefClkDiv(value) (((value)&0x7)<<8)
#define AR7_ResAdj (1<<11)
#define AR7_NegPhase (1<<12)
#define AR7_Track (1<<13)
#define AR7_MTimer(value) (((value) & 0x1ff)<<15)
#define AR14_16BitMode (1<<4)
#define AR8I_IFIFO1(reg) ((reg) & 0x1ffff)
#define AR8I_Slope1(reg) ((reg) & (1<<17) ? 1 : 0)
#define AR8I_StartN1(reg) (((reg) >> 18) & 0xff)
#define AR8I_ChaCode1(reg) (((reg) >> 26) & 0x3)
#define AR9I_IFIFO2(reg) ((reg) & 0x1ffff)
#define AR9I_Slope2(reg) ((reg) & (1<<17) ? 1 : 0)
#define AR9I_StartN2(reg) (((reg) >> 18) & 0xff)
#define AR9I_ChaCode2(reg) (((reg) >> 26) & 0x3)
#define AR8R_IFIFO1(reg) ((reg) & 0x3fffff)
#define AR9R_IFIFO2(reg) ((reg) & 0x3fffff)
#define AR11_StopCounter0(num) ((num) & 0xff)
#define AR11_StopCounter1(num) (((num) & 0xff) << 8)
#define AR11_HFifoErrU(num) (1 << (num+16))
#define AR11_IFifoErrU(num) (1 << (num+24))
#define AR11_NotLockErrU (1 << 26)
#define AR12_HFifoE (1<<11)
#define AR12_NotLocked (1<<10)
#endif
......@@ -3,7 +3,7 @@
* File : fd_main_regs.h
* Author : auto-generated by wbgen2 from fd_main_wishbone_slave.wb
* Created : Mon Jun 4 13:42:20 2012
* Created : Fri Feb 15 12:07:16 2013
* Standard : ANSI C
THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE fd_main_wishbone_slave.wb
......@@ -64,7 +64,7 @@
/* definitions for field: PLL Locked in reg: Global Control Register */
#define FD_GCR_DDR_LOCKED WBGEN2_GEN_MASK(2, 1)
/* definitions for field: Mezzanice Present in reg: Global Control Register */
/* definitions for field: Mezzanine Present in reg: Global Control Register */
#define FD_GCR_FMC_PRESENT WBGEN2_GEN_MASK(3, 1)
/* definitions for register: Timing Control Register */
......@@ -99,46 +99,46 @@
/* definitions for register: Time Register - sub-second 125 MHz clock cycles */
/* definitions for register: TDC Data Register */
/* definitions for register: Host-driven TDC Data Register */
/* definitions for register: TDC control/status reg */
/* definitions for register: Host-driven TDC Control/Status */
/* definitions for field: Start TDC write in reg: TDC control/status reg */
/* definitions for field: Write to TDC in reg: Host-driven TDC Control/Status */
#define FD_TDCSR_WRITE WBGEN2_GEN_MASK(0, 1)
/* definitions for field: Start TDC read in reg: TDC control/status reg */
/* definitions for field: Read from TDC in reg: Host-driven TDC Control/Status */
#define FD_TDCSR_READ WBGEN2_GEN_MASK(1, 1)
/* definitions for field: Empty flag in reg: TDC control/status reg */
/* definitions for field: Empty flag in reg: Host-driven TDC Control/Status */
#define FD_TDCSR_EMPTY WBGEN2_GEN_MASK(2, 1)
/* definitions for field: Start enable in reg: TDC control/status reg */
/* definitions for field: Stop enable in reg: Host-driven TDC Control/Status */
#define FD_TDCSR_STOP_EN WBGEN2_GEN_MASK(3, 1)
/* definitions for field: Start disable in reg: TDC control/status reg */
/* definitions for field: Start disable in reg: Host-driven TDC Control/Status */
#define FD_TDCSR_START_DIS WBGEN2_GEN_MASK(4, 1)
/* definitions for field: Stop enable in reg: TDC control/status reg */
/* definitions for field: Start enable in reg: Host-driven TDC Control/Status */
#define FD_TDCSR_START_EN WBGEN2_GEN_MASK(5, 1)
/* definitions for field: Stop disable in reg: TDC control/status reg */
/* definitions for field: Stop disable in reg: Host-driven TDC Control/Status */
#define FD_TDCSR_STOP_DIS WBGEN2_GEN_MASK(6, 1)
/* definitions for field: write 1: Pulse the Alutrigger line in reg: TDC control/status reg */
/* definitions for field: Pulse <code>Alutrigger</code> line in reg: Host-driven TDC Control/Status */
#define FD_TDCSR_ALUTRIG WBGEN2_GEN_MASK(7, 1)
/* definitions for register: Calibration register */
/* definitions for field: Triggers calibration pulses in reg: Calibration register */
/* definitions for field: Generate calibration pulses (type 1 calibration) in reg: Calibration register */
#define FD_CALR_CAL_PULSE WBGEN2_GEN_MASK(0, 1)
/* definitions for field: PPS Calibration output enable in reg: Calibration register */
#define FD_CALR_CAL_PPS WBGEN2_GEN_MASK(1, 1)
/* definitions for field: Produce DDMTD calibration pattern in reg: Calibration register */
/* definitions for field: Produce DDMTD calibration pattern (type 2 calibration) in reg: Calibration register */
#define FD_CALR_CAL_DMTD WBGEN2_GEN_MASK(2, 1)
/* definitions for field: Enable pulse generation in reg: Calibration register */
/* definitions for field: Calibration pulse output select/mask in reg: Calibration register */
#define FD_CALR_PSEL_MASK WBGEN2_GEN_MASK(3, 4)
#define FD_CALR_PSEL_SHIFT 3
#define FD_CALR_PSEL_W(value) WBGEN2_GEN_WRITE(value, 3, 4)
......@@ -171,16 +171,16 @@
/* definitions for register: Acam Timestamp Merging Control Register */
/* definitions for field: Wraparound Coarse Threshold in reg: Acam Timestamp Merging Control Register */
#define FD_ATMCR_C_THR_MASK WBGEN2_GEN_MASK(0, 4)
#define FD_ATMCR_C_THR_MASK WBGEN2_GEN_MASK(0, 8)
#define FD_ATMCR_C_THR_SHIFT 0
#define FD_ATMCR_C_THR_W(value) WBGEN2_GEN_WRITE(value, 0, 4)
#define FD_ATMCR_C_THR_R(reg) WBGEN2_GEN_READ(reg, 0, 4)
#define FD_ATMCR_C_THR_W(value) WBGEN2_GEN_WRITE(value, 0, 8)
#define FD_ATMCR_C_THR_R(reg) WBGEN2_GEN_READ(reg, 0, 8)
/* definitions for field: Wraparound Fine Threshold in reg: Acam Timestamp Merging Control Register */
#define FD_ATMCR_F_THR_MASK WBGEN2_GEN_MASK(4, 23)
#define FD_ATMCR_F_THR_SHIFT 4
#define FD_ATMCR_F_THR_W(value) WBGEN2_GEN_WRITE(value, 4, 23)
#define FD_ATMCR_F_THR_R(reg) WBGEN2_GEN_READ(reg, 4, 23)
#define FD_ATMCR_F_THR_MASK WBGEN2_GEN_MASK(8, 23)
#define FD_ATMCR_F_THR_SHIFT 8
#define FD_ATMCR_F_THR_W(value) WBGEN2_GEN_WRITE(value, 8, 23)
#define FD_ATMCR_F_THR_R(reg) WBGEN2_GEN_READ(reg, 8, 23)
/* definitions for register: Acam Start Offset Register */
......@@ -399,9 +399,9 @@
#define FD_REG_TM_SECL 0x00000014
/* [0x18]: REG Time Register - sub-second 125 MHz clock cycles */
#define FD_REG_TM_CYCLES 0x00000018
/* [0x1c]: REG TDC Data Register */
/* [0x1c]: REG Host-driven TDC Data Register */
#define FD_REG_TDR 0x0000001c
/* [0x20]: REG TDC control/status reg */
/* [0x20]: REG Host-driven TDC Control/Status */
#define FD_REG_TDCSR 0x00000020
/* [0x24]: REG Calibration register */
#define FD_REG_CALR 0x00000024
......
This diff is collapsed.
/*
FmcDelay1ns4Cha (a.k.a. The Fine Delay Card)
User-space driver/library
Private includes
Tomasz Włostowski/BE-CO-HT, 2011
(c) Copyright CERN 2011
Licensed under LGPL 2.1
*/
#ifndef __FDELAY_PRIVATE_H
#define __FDELAY_PRIVATE_H
#include <stdint.h>
/* SPI Bus chip selects */
#define CS_DAC 0 /* AD9516 PLL */
#define CS_PLL 1 /* AD9516 PLL */
#define CS_GPIO 2 /* MCP23S17 GPIO */
#define CS_NONE 3
/* MCP23S17 GPIO expander pin locations: bit 8 = select bank 2, bits 7..0 = mask of the pin in the selected bank */
#define SGPIO_TERM_EN (1<<0) /* Input termination enable (1 = on) */
#define SGPIO_OUTPUT_EN(x) (1<<(6-x)) /* Output driver enable (1 = on) */
#define SGPIO_TRIG_SEL (1<<6) /* TDC trigger select (0 = trigger input, 1 = FPGA) */
#define SGPIO_CAL_EN (1<<7) /* Calibration mode enable (0 = on) */
/* ACAM TDC operation modes */
#define ACAM_RMODE 0
#define ACAM_IMODE 1
/* MCP23S17 register addresses (only ones which are used by the lib) */
#define MCP_IODIR 0x0
#define MCP_IPOL 0x1
#define MCP_OLAT 0x14
#define MCP_IOCON 0x0a
#define MCP_GPIO 0x12
/* Number of fractional bits in the timestamps/time definitions. Must be consistent with the HDL bitstream. */
#define FDELAY_FRAC_BITS 12
/* Fractional bits shifted away when converting the fine (< 8ns) part to fit the range of SY89295 delay line. */
#define FDELAY_SCALER_SHIFT 12
/* Number of delay line taps */
#define FDELAY_NUM_TAPS 1024
/* How many times each calibration measurement will be averaged */
#define FDELAY_CAL_AVG_STEPS 1024
/* Fine Delay Card Magic ID */
#define FDELAY_MAGIC_ID 0xf19ede1a
/* RSTR Register value which triggers a reset of the FD Core */
#define FDELAY_RSTR_TRIGGER 0xdeadbeef
/* Calibration eeprom I2C address */
#define EEPROM_ADDR 0x50
/*
FmcDelay1ns4Cha (a.k.a. The Fine Delay Card)
User-space driver/library
Private includes
Tomasz Włostowski/BE-CO-HT, 2011
(c) Copyright CERN 2011
Licensed under LGPL 2.1
*/
#ifndef __FDELAY_PRIVATE_H
#define __FDELAY_PRIVATE_H
#include <stdint.h>
/* SPI Bus chip selects */
#define CS_DAC 0 /* AD9516 PLL */
#define CS_PLL 1 /* AD9516 PLL */
#define CS_GPIO 2 /* MCP23S17 GPIO */
#define CS_NONE 3
/* MCP23S17 GPIO expander pin locations: bit 8 = select bank 2, bits 7..0 = mask of the pin in the selected bank */
#define SGPIO_TERM_EN (1<<0) /* Input termination enable (1 = on) */
#define SGPIO_OUTPUT_EN(x) (1<<(6-x)) /* Output driver enable (1 = on) */
#define SGPIO_TRIG_SEL (1<<6) /* TDC trigger select (0 = trigger input, 1 = FPGA) */
#define SGPIO_CAL_EN (1<<7) /* Calibration mode enable (0 = on) */
/* ACAM TDC operation modes */
#define ACAM_RMODE 0
#define ACAM_IMODE 1
#define ACAM_GMODE 2
/* MCP23S17 register addresses (only ones which are used by the lib) */
#define MCP_IODIR 0x0
#define MCP_IPOL 0x1
#define MCP_OLAT 0x14
#define MCP_IOCON 0x0a
#define MCP_GPIO 0x12
/* Number of fractional bits in the timestamps/time definitions. Must be consistent with the HDL bitstream. */
#define FDELAY_FRAC_BITS 12
/* Fractional bits shifted away when converting the fine (< 8ns) part to fit the range of SY89295 delay line. */
#define FDELAY_SCALER_SHIFT 12
/* Number of delay line taps */
#define FDELAY_NUM_TAPS 1024
/* How many times each calibration measurement will be averaged */
#define FDELAY_CAL_AVG_STEPS 1024
/* Fine Delay Card Magic ID */
#define FDELAY_MAGIC_ID 0xf19ede1a
/* RSTR Register value which triggers a reset of the FD Core */
#define FDELAY_RSTR_TRIGGER 0xdeadbeef
/* Calibration eeprom I2C address */
#define EEPROM_ADDR 0x50
/* Default TDC parameters. Formerly kept in the EEPROM, now hardcoded. */
#define FD_ATMCR_VALUE (26 | (1500 << 8))
#define FD_ASOR_VALUE 17000
#define FD_ADSFR_VALUE 84977
#define FD_ACAM_START_OFFSET_VALUE 10000
#define EEPROM_CALIB_OFFSET (6*1024)
struct fd_calib {
int64_t frr_poly[3]; /* SY89295 delay/temp poly coeffs */
uint32_t magic; /* magic ID: 0xf19ede1a */
uint32_t zero_offset[4]; /* Output zero offset, fixed point */
uint32_t adsfr_val; /* ADSFR register value */
uint32_t acam_start_offset; /* ACAM Start offset value */
uint32_t atmcr_val; /* ATMCR register value */
uint32_t tdc_zero_offset; /* Zero offset of the TDC, in ps */
/* The user can add a signed offset, in picoseconds */
int32_t tdc_user_offset;
int32_t ch_user_offset[4];
int32_t tdc_flags;
int32_t out_zero_offset[4]; /* Output zero offset, fixed point */
int32_t tdc_zero_offset; /* Zero offset of the TDC, in ps */
uint32_t vcxo_default_tune;
};
struct fd_calib_on_eeprom {
uint32_t magic; /* magic ID: 0xf19ede1a */
uint32_t hash;
uint16_t size;
uint16_t version;
uint32_t date;
struct fd_calib calib;
};
/* Internal state of the fine delay card */
struct fine_delay_hw
{
uint32_t base_addr; /* Base address of the core */
uint32_t base_onewire; /* Base address of the core */
uint32_t base_i2c; /* SPI Controller offset */
uint32_t acam_addr; /* Current state of ACAM's address lines */
double acam_bin; /* bin size of the ACAM TDC - calculated for 31.25 MHz reference */
uint32_t frr_offset[4]; /* Offset between the FRR measured at a known temperature at startup and poly-fitted FRR */
uint32_t frr_cur[4]; /* Fine range register for each output, current value (after online temp. compensation) */
int32_t cal_temp; /* SY89295 calibration temperature in 1/16 degC units */
int32_t board_temp; /* Current temperature of the board, unit = 1/16 degC */
int wr_enabled;
int wr_state;
int raw_mode;
int do_long_tests;
struct fd_calib calib;
int64_t input_user_offset, output_user_offset;
};
/* some useful access/declaration macros */
#define fd_writel(data, addr) dev->writel(dev->priv_io, data, (hw->base_addr + (addr)))
#define fd_readl(addr) dev->readl(dev->priv_io, (hw->base_addr + (addr)))
#define fd_decl_private(dev) struct fine_delay_hw *hw = (struct fine_delay_hw *) dev->priv_fd;
#endif
/* Internal state of the fine delay card */
struct fine_delay_hw
{
uint32_t base_addr; /* Base address of the core */
uint32_t base_onewire; /* Base address of the core */
uint32_t base_i2c; /* SPI Controller offset */
uint32_t acam_addr; /* Current state of ACAM's address lines */
double acam_bin; /* bin size of the ACAM TDC - calculated for 31.25 MHz reference */
uint32_t frr_offset[4]; /* Offset between the FRR measured at a known temperature at startup and poly-fitted FRR */
uint32_t frr_cur[4]; /* Fine range register for each output, current value (after online temp. compensation) */
int32_t cal_temp; /* SY89295 calibration temperature in 1/16 degC units */
int32_t board_temp; /* Current temperature of the board, unit = 1/16 degC */
int wr_enabled;
int wr_state;
int raw_mode;
int do_long_tests;
struct fd_calib calib;
};
/* some useful access/declaration macros */
#define fd_writel(data, addr) dev->writel(dev->priv_io, data, (hw->base_addr + (addr)))
#define fd_readl(addr) dev->readl(dev->priv_io, (hw->base_addr + (addr)))
#define fd_decl_private(dev) struct fine_delay_hw *hw = (struct fine_delay_hw *) dev->priv_fd;
#endif
#ifndef __I2C_MASTER_H
#define __I2C_MASTER_H
#include <stdint.h>
#include "fdelay_lib.h"
void mi2c_init(fdelay_device_t *dev);
int eeprom_read(fdelay_device_t *dev, uint8_t i2c_addr, uint32_t offset, uint8_t *buf, size_t size);
int eeprom_write(fdelay_device_t *dev, uint8_t i2c_addr, uint32_t offset, uint8_t *buf, size_t size);
#endif
#ifndef __I2C_MASTER_H
#define __I2C_MASTER_H
#include <stdint.h>
#include "fdelay_lib.h"
void mi2c_init(fdelay_device_t *dev);
int eeprom_read(fdelay_device_t *dev, uint8_t i2c_addr, uint32_t offset, uint8_t *buf, size_t size);
int eeprom_write(fdelay_device_t *dev, uint8_t i2c_addr, uint32_t offset, uint8_t *buf, size_t size);
#endif
#ifndef ONEWIRE_H_INCLUDED
#define ONEWIRE_H_INCLUDED
#ifndef ONEWIRE_H_INCLUDED
#define ONEWIRE_H_INCLUDED
#include "fdelay_lib.h"
int ds18x_init(fdelay_device_t *dev);
int ds18x_read_temp(fdelay_device_t *dev, int *temp_r);
#endif // ONEWIRE_H_INCLUDED
#endif // ONEWIRE_H_INCLUDED
const struct {int reg; uint8_t val; } ad9516_regs[] = {
{0x0000, 0x99},
{0x0001, 0x00},
{0x0002, 0x10},
{0x0003, 0xC3},
{0x0004, 0x00},
{0x0010, 0x7C},
{0x0011, 0x05},
{0x0012, 0x00},
{0x0013, 0x0C},
{0x0014, 0x12},
{0x0015, 0x00},
{0x0016, 0x05},
{0x0017, 0xb4}, /* PLL_STATUS = Lock Detect */
{0x0018, 0x07},
{0x0019, 0x00},
{0x001A, 0x00},
{0x001B, 0xE0},
{0x001C, 0x02},
{0x001D, 0x00},
{0x001E, 0x00},
{0x001F, 0x0E},
{0x00A0, 0x01},
{0x00A1, 0x00},
{0x00A2, 0x00},
{0x00A3, 0x01},
{0x00A4, 0x00},
{0x00A5, 0x00},
{0x00A6, 0x01},
{0x00A7, 0x00},
{0x00A8, 0x00},
{0x00A9, 0x01},
{0x00AA, 0x00},
{0x00AB, 0x00},
{0x00F0, 0x08},
{0x00F1, 0x08},
{0x00F2, 0x08},
{0x00F3, 0x18}, /* out3 inverted */
{0x00F4, 0x00},
{0x00F5, 0x08},
{0x0140, 0x5A},
{0x0141, 0x5A},
{0x0142, 0x5B},
{0x0143, 0x42},
{0x0190, 0x00},
{0x0191, 0x80},
{0x0192, 0x00},
{0x0193, 0x00},
{0x0194, 0x80},
{0x0195, 0x00},
{0x0196, 0xFF},
{0x0197, 0x00},
{0x0198, 0x00},
{0x0199, 0x33},
{0x019A, 0x00},
{0x019B, 0x11},
{0x019C, 0x20},
{0x019D, 0x00},
{0x019E, 0x00},
{0x019F, 0x00},
{0x01A0, 0x11},
{0x01A1, 0x20},
{0x01A2, 0x00},
{0x01A3, 0x00},
{0x01E0, 0x04}, /* VCODIV = 6 */
{0x01E1, 0x02},
{0x0230, 0x00},
{0x0231, 0x00},
{0x0232, 0x00},
{-1, 0}};
const struct {int reg; uint8_t val; } ad9516_regs[] = {
{0x0000, 0x99},
{0x0001, 0x00},
{0x0002, 0x10},
{0x0003, 0xC3},
{0x0004, 0x00},
{0x0010, 0x7C},
{0x0011, 0x05},
{0x0012, 0x00},
{0x0013, 0x0C},
{0x0014, 0x12},
{0x0015, 0x00},
{0x0016, 0x05},
{0x0017, 0xb4}, /* PLL_STATUS = Lock Detect */
{0x0018, 0x07},
{0x0019, 0x00},
{0x001A, 0x00},
{0x001B, 0xE0},
{0x001C, 0x02},
{0x001D, 0x00},
{0x001E, 0x00},
{0x001F, 0x0E},
{0x00A0, 0x01},
{0x00A1, 0x00},
{0x00A2, 0x00},
{0x00A3, 0x01},
{0x00A4, 0x00},
{0x00A5, 0x00},
{0x00A6, 0x01},
{0x00A7, 0x00},
{0x00A8, 0x00},
{0x00A9, 0x01},
{0x00AA, 0x00},
{0x00AB, 0x00},
{0x00F0, 0x08},
{0x00F1, 0x08},
{0x00F2, 0x08},
{0x00F3, 0x18}, /* out3 inverted */
{0x00F4, 0x00},
{0x00F5, 0x08},
{0x0140, 0x5A},
{0x0141, 0x5A},
{0x0142, 0x5B},
{0x0143, 0x42},
{0x0190, 0x00},
{0x0191, 0x80},
{0x0192, 0x00},
{0x0193, 0x00},
{0x0194, 0x80},
{0x0195, 0x00},
{0x0196, 0xFF},
{0x0197, 0x00},
{0x0198, 0x00},
{0x0199, 0x33},
{0x019A, 0x00},
{0x019B, 0x11},
{0x019C, 0x20},
{0x019D, 0x00},
{0x019E, 0x00},
{0x019F, 0x00},
{0x01A0, 0x11},
{0x01A1, 0x20},
{0x01A2, 0x00},
{0x01A3, 0x00},
{0x01E0, 0x04}, /* VCODIV = 6 */
{0x01E1, 0x02},
{0x0230, 0x00},
{0x0231, 0x00},
{0x0232, 0x00},
{-1, 0}};
/*
* Public header for the raw I/O interface for PCI or PCI express interfaces
*
* Copyright (C) 2010 CERN (www.cern.ch)
* Author: Alessandro Rubini <rubini@gnudd.com>
*
* Released according to the GNU GPL, version 2 or any later version.
*
* This work is part of the White Rabbit project, a research effort led
* by CERN, the European Institute for Nuclear Research.
*/
#ifndef __RAWRABBIT_H__
#define __RAWRABBIT_H__
#include <linux/types.h>
#include <linux/ioctl.h>
#ifdef __KERNEL__ /* The initial part of the file is driver-internal stuff */
#include <linux/pci.h>
#include <linux/completion.h>
#include <linux/workqueue.h>
#include <linux/firmware.h>
#include <linux/wait.h>
#include <linux/completion.h>
struct rr_devsel;
struct rr_dev {
struct rr_devsel *devsel;
struct pci_driver *pci_driver;
struct pci_device_id *id_table;
struct pci_dev *pdev; /* non-null after pciprobe */
struct mutex mutex;
wait_queue_head_t q;
void *dmabuf;
char *fwname;
struct timespec irqtime;
unsigned long irqcount;
struct completion complete;
struct resource *area[3]; /* bar 0, 2, 4 */
void *remap[3]; /* ioremap of bar 0, 2, 4 */
unsigned long flags;
struct work_struct work;
const struct firmware *fw;
struct completion fw_load;
void (*load_program)(struct rr_dev *); /* lm32 */
int usecount;
#ifdef IS_SPEC_DEMO
struct miscdevice misc;
char miscname[32]; /* "spec-demo-<bus>-<slot> */
struct list_head list;
#endif
};
extern char *rr_fwname; /* module parameter. If "" then defaults apply */
#define RR_FLAG_REGISTERED 0x00000001
#define RR_FLAG_IRQDISABLE 0x00000002
#define RR_FLAG_IRQREQUEST 0x00000002
#define RR_PROBE_TIMEOUT (HZ) /* for pci_register_drv */
/* These two live in ./loader.c */
extern void rr_ask_firmware(struct rr_dev *dev);
extern void rr_load_firmware(struct work_struct *work);
/* And, for the spec only, this is in ./spec-loader.c */
extern void spec_ask_program(struct rr_dev *dev);
#endif /* __KERNEL__ */
/* By default, the driver registers for this vendor/devid */
#define RR_DEFAULT_VENDOR 0x1a39
#define RR_DEFAULT_DEVICE 0x0004
#define RR_DEFAULT_FWNAME "rrabbit-%P-%p@%b"
#define RR_MAX_FWNAME_SIZE 64
#define RR_DEFAULT_BUFSIZE (1<<20) /* 1MB */
#define RR_PLIST_SIZE 4096 /* no PAGE_SIZE in user space */
#define RR_PLIST_LEN (RR_PLIST_SIZE / sizeof(void *))
#define RR_MAX_BUFSIZE (RR_PLIST_SIZE * RR_PLIST_LEN)
/* This structure is used to select the device to be accessed, via ioctl */
struct rr_devsel {
__u16 vendor;
__u16 device;
__u16 subvendor; /* RR_DEVSEL_UNUSED to ignore subvendor/dev */
__u16 subdevice;
__u16 bus; /* RR_DEVSEL_UNUSED to ignore bus and devfn */
__u16 devfn;
};
#define RR_DEVSEL_UNUSED 0xffff
/* Offsets for BAR areas in llseek() and/or ioctl */
#define RR_BAR_0 0x00000000
#define RR_BAR_2 0x20000000
#define RR_BAR_4 0x40000000
#define RR_BAR_BUF 0xc0000000 /* The DMA buffer */
#define RR_IS_DMABUF(addr) ((addr) >= RR_BAR_BUF)
#define __RR_GET_BAR(x) ((x) >> 28)
#define __RR_SET_BAR(x) ((x) << 28)
#define __RR_GET_OFF(x) ((x) & 0x0fffffff)
static inline int rr_is_valid_bar(unsigned long address)
{
int bar = __RR_GET_BAR(address);
return bar == 0 || bar == 2 || bar == 4 || bar == 0x0c;
}
static inline int rr_is_dmabuf_bar(unsigned long address)
{
int bar = __RR_GET_BAR(address);
return bar == 0x0c;
}
struct rr_iocmd {
__u32 address; /* bar and offset */
__u32 datasize; /* 1 or 2 or 4 or 8 */
union {
__u8 data8;
__u16 data16;
__u32 data32;
__u64 data64;
};
};
/* ioctl commands */
#define __RR_IOC_MAGIC '4' /* random or so */
#define RR_DEVSEL _IOW(__RR_IOC_MAGIC, 0, struct rr_devsel)
#define RR_DEVGET _IOR(__RR_IOC_MAGIC, 1, struct rr_devsel)
#define RR_READ _IOWR(__RR_IOC_MAGIC, 2, struct rr_iocmd)
#define RR_WRITE _IOW(__RR_IOC_MAGIC, 3, struct rr_iocmd)
#define RR_IRQWAIT _IO(__RR_IOC_MAGIC, 4)
#define RR_IRQENA _IO(__RR_IOC_MAGIC, 5)
#define RR_GETDMASIZE _IO(__RR_IOC_MAGIC, 6)
/* #define RR_SETDMASIZE _IO(__RR_IOC_MAGIC, 7, unsigned long) */
#define RR_GETPLIST _IO(__RR_IOC_MAGIC, 8) /* returns a whole page */
#define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct dirent [2])
/* Registers from the gennum header files */
enum {
GNGPIO_BASE = 0xA00,
GNGPIO_DIRECTION_MODE = GNGPIO_BASE + 0x4,
GNGPIO_OUTPUT_ENABLE = GNGPIO_BASE + 0x8,
GNGPIO_OUTPUT_VALUE = GNGPIO_BASE + 0xC,
GNGPIO_INPUT_VALUE = GNGPIO_BASE + 0x10,
FCL_BASE = 0xB00,
FCL_CTRL = FCL_BASE,
FCL_STATUS = FCL_BASE + 0x4,
FCL_IODATA_IN = FCL_BASE + 0x8,
FCL_IODATA_OUT = FCL_BASE + 0xC,
FCL_EN = FCL_BASE + 0x10,
FCL_TIMER_0 = FCL_BASE + 0x14,
FCL_TIMER_1 = FCL_BASE + 0x18,
FCL_CLK_DIV = FCL_BASE + 0x1C,
FCL_IRQ = FCL_BASE + 0x20,
FCL_TIMER_CTRL = FCL_BASE + 0x24,
FCL_IM = FCL_BASE + 0x28,
FCL_TIMER2_0 = FCL_BASE + 0x2C,
FCL_TIMER2_1 = FCL_BASE + 0x30,
FCL_DBG_STS = FCL_BASE + 0x34,
FCL_FIFO = 0xE00,
PCI_SYS_CFG_SYSTEM = 0x800
};
#endif /* __RAWRABBIT_H__ */
#ifndef __RR_IO_H
#define __RR_IO_H
#include <stdint.h>
#include <rawrabbit.h>
int rr_bind(int a_fd);
int rr_init(int bus, int devfn);
int rr_writel(uint32_t data, uint32_t addr);
uint32_t rr_readl(uint32_t addr);
int rr_load_bitstream(const void *data, int size8);
int rr_load_bitstream_from_file(const char *file_name);
#endif
......@@ -41,6 +41,52 @@ uint32_t wait_promptTimeout;
/* WR core shell communication functions */
/* Waits for a WR Core and returns the output of the previous command in rv */
static void wait_prompt(fdelay_device_t *dev, char *rv)
{
char buf[16384],c;
int pos = 0;
memset(buf, 0, sizeof(buf));
while(pos < sizeof(buf))
{
if(spec_vuart_rx(dev->priv_io, &c, 1) == 1)
{
buf[pos++] = c;
if(pos >= 5 && !strcmp(buf + pos - 5, "wrc# "))
{
int old_pos;
if(!rv)
return;
while(pos>0) if(buf[pos]=='\n'||buf[pos]=='\r')
break;
else
pos--;
pos-=2;
old_pos = pos;
while(pos>0) if(buf[pos]=='\n'||buf[pos]=='\r')
break;
else
pos--;
strncpy(rv, buf+pos+1, old_pos - pos);
rv[old_pos-pos]=0;
return;
}
}
}
dbg("Failure: shell buffer overflow.\n");
exit(1);
}
static void shell_purge(fdelay_device_t *dev)
{
char c='\r';
......@@ -56,68 +102,26 @@ static void shell_purge(fdelay_device_t *dev)
}
}
/* executes a shell command on the associated WR core */
static int wrc_shell_exec(fdelay_device_t *dev, const char *cmd, char *retval, int64_t timeout)
static int wrc_shell_exec(fdelay_device_t *dev, const char *cmd, char *retval)
{
char c;
char buf[16384];
int buf_pos = 0, i;
shell_purge(dev);
while(spec_vuart_rx(dev->priv_io, &c, 1) == 1);
spec_vuart_tx(dev->priv_io, (char *)cmd, strlen(cmd));
spec_vuart_tx(dev->priv_io, "\r", 1);
int64_t start_tics = get_tics();
for(;;)
{
if(spec_vuart_rx(dev->priv_io, &c, 1) == 1)
buf[buf_pos++] = c;
if(buf_pos >= sizeof(buf))
{
return -1;
}
if(get_tics() - start_tics > timeout)
break;
}
buf[buf_pos] = 0;
wait_prompt(dev, retval);
if(retval)
{
int p1 = -1,p2 = -1;
strcpy(retval, "");
/* fprintf(stderr,"BUF_DUMP:\n");
for(i=0;i<buf_pos;i++)
fprintf(stderr,"%d: '%c'\n", i, buf[i]);
fprintf(stderr,"END_BUF_DUMP\n");*/
for(i=buf_pos-1;i>=0; i--) if(buf[i] == '\n' || buf[i] == '\r')
{ p2 = i; break; }
i-=2;
for(;i>=0; i--) if(buf[i] == '\n' || buf[i] == '\r')
{ p1 = i; break; }
if(p1 + 1 == p2)
strcpy(retval, "");
else
strncpy(retval, buf+p1+1, p2-p1);
for(i=0;i<strlen(retval);i++)
if(retval[i] == '\n' || retval[i] == '\r')
retval[i] = 0;
dbg("wr_core exec '%s', retval: '%s'\n", cmd, retval);
}
return 0;
}
#define DMTD_N_AVGS 10 /* number of average samples */
#define DELAY_SETPOINT 500000 /* test delay value */
#define DMTD_N_AVGS 100 /* number of average samples */
#define DELAY_SETPOINT 750000 /* test delay value */
#define DMTD_PULSE_PERIOD 144
#define DMTD_OUTPUT_PERIOD (16384 * DMTD_PULSE_PERIOD / 2) /* period of the DDMTD output signal in 62.5 MHz clock cycles */
......@@ -177,9 +181,10 @@ int calibrate_channel(fdelay_device_t *dev, int channel, double *mean, double *s
fd_writel(FD_CALR_PSEL_W(0), FD_REG_CALR);
/* Configure the output to introduce DELAY_SETPOINT delay (but with fixed offset set to 0)*/
hw->calib.zero_offset[channel-1] = 0;
hw->calib.out_zero_offset[channel-1] = 0;
hw->calib.tdc_zero_offset = 0;
fdelay_configure_output(dev, channel, 1, (int64_t)DELAY_SETPOINT, 200000LL, 0LL, 1);
fdelay_configure_output(dev, channel, 1, (int64_t)DELAY_SETPOINT, 300000LL, 0LL, 1);
/* Disable ALL outputs to prevent the calibration pulses from driving whatever
is connected to the board */
......@@ -213,7 +218,7 @@ int calibrate_channel(fdelay_device_t *dev, int channel, double *mean, double *s
/* Get DMTD_N_AVGS samples to reduce error */
n_in = n_out = 0;
int64_t ts = get_tics();
while((n_in < DMTD_N_AVGS || n_out < DMTD_N_AVGS) && ((get_tics()-ts) < 1000000))
while((n_in < DMTD_N_AVGS || n_out < DMTD_N_AVGS) && ((get_tics()-ts) < 10000000))
{
if(read_dmtd(dev, &ch_in, 0))
{
......@@ -227,7 +232,7 @@ int calibrate_channel(fdelay_device_t *dev, int channel, double *mean, double *s
samples_out[n_out++] = ch_out.phase;
}
}
if((get_tics()-ts) >= 1000000)
if((get_tics()-ts) >= 10000000)
{
dbg("%s has timed out\n", __FUNCTION__);
return -1;
......@@ -254,12 +259,13 @@ int calibrate_channel(fdelay_device_t *dev, int channel, double *mean, double *s
s+=((double)delta[i]-avg) * ((double)delta[i]-avg);
*std = sqrt(s / (double)(DMTD_N_AVGS-1)) * scalefact;
fd_writel(FD_CALR_PSEL_W(0), FD_REG_CALR);
/* Reset to normal trigger and disable input and output */
if(sgpio_set_pin(dev, SGPIO_TRIG_SEL, 1) < 0)
return -1;
fdelay_configure_trigger(dev, 0, 0);
fdelay_configure_output(dev, channel, 0, (int64_t)DELAY_SETPOINT, 200000LL, 0LL, 1);
return 0;
}
......@@ -270,8 +276,9 @@ int fdelay_dmtd_calibration(fdelay_device_t *dev, const char *filename, uint32_t
char c;
int i, error = 0;
fd_decl_private(dev);
wait_promptTimeout = *userTimeout;
int64_t base = 0, prev_tag = -1;
int64_t base = 0, prev_tag = -1;
if(spec_load_lm32(dev->priv_io, filename, 0xc0000))
{
......@@ -284,23 +291,23 @@ int fdelay_dmtd_calibration(fdelay_device_t *dev, const char *filename, uint32_t
/* Configure the WR core to produce a proper calibration clock: */
/* Disable PTP and enter free-running master mode */
if(wrc_shell_exec(dev, "ptp stop", resp, 100000LL) < 0)
if(wrc_shell_exec(dev, "ptp stop", resp) < 0)
return -1;
if(wrc_shell_exec(dev, "mode master", resp, 5000000LL) < 0)
if(wrc_shell_exec(dev, "mode master", resp) < 0)
return -1;
/* And lock the DMTD oscillator to the FMC clock instead of the SPEC 125 MHz oscillator. Set the FMC VCO DAC to 0
to have some headroom */
if(wrc_shell_exec(dev, "pll sdac 1 0", resp, 100000LL) < 0)
if(wrc_shell_exec(dev, "pll sdac 1 0", resp) < 0)
return -1;
if(wrc_shell_exec(dev, "pll init 2 1 1", resp, 100000LL) < 0)
if(wrc_shell_exec(dev, "pll init 2 1 1", resp) < 0)
return -1;
/* Wait until the PLL locks... */
int64_t ts = get_tics();
while(1)
{
if(wrc_shell_exec(dev, "pll cl 0", resp, 100000LL) < 0)
if(wrc_shell_exec(dev, "pll cl 0", resp) < 0)
return -1;
if(!strcmp(resp, "1"))
break;
......@@ -318,17 +325,17 @@ int fdelay_dmtd_calibration(fdelay_device_t *dev, const char *filename, uint32_t
for(i=1;i<=4;i++)
{
dbg("\n\nPerforming DDMTD delay calibration of channel %d\n", i);
dbg("\n\nPerforming DDMTD-based calibration of channel %d\n", i);
if(calibrate_channel(dev, i, &mean_out[i-1], &std_out[i-1]) < 0)
{
dbg("Failed, DMTD not possible for channel %d, DMTD Tag Ready flag is not coming high\n", i);
hw->calib.zero_offset[i-1] = 0;
dbg("Failed, DDMTD calibration failure for channel %d, DMTD Tag Ready flag is not coming high\n", i);
hw->calib.out_zero_offset[i-1] = 0;
error = 1;
}
else
{
dbg("Channel %d: delay %.0f ps, std %.0f ps.\n", i, mean_out[i-1], std_out[i-1]);
hw->calib.zero_offset[i-1] = mean_out[i-1] - 500000;
hw->calib.out_zero_offset[i-1] = mean_out[i-1] - DELAY_SETPOINT - hw->calib.tdc_zero_offset;
}
}
return error ? -1 : 0;
......
This diff is collapsed.
#include <stdio.h>
#include "fdelay_lib.h"
#include "fdelay_private.h"
#include "fd_main_regs.h"
#define M_SDA_OUT(x) \
{ \
if(x) \
fd_writel(fd_readl(FD_REG_I2CR) | FD_I2CR_SDA_OUT, FD_REG_I2CR); \
else \
fd_writel(fd_readl(FD_REG_I2CR) & (~FD_I2CR_SDA_OUT), FD_REG_I2CR); \
udelay(10); \
}
#define M_SCL_OUT(x) \
{ \
if(x) \
fd_writel(fd_readl(FD_REG_I2CR) | FD_I2CR_SCL_OUT, FD_REG_I2CR); \
else \
fd_writel(fd_readl(FD_REG_I2CR) & (~FD_I2CR_SCL_OUT), FD_REG_I2CR); \
udelay(10); \
}
#define M_SDA_IN ((fd_readl(FD_REG_I2CR) & FD_I2CR_SDA_IN) ? 1 : 0)
static void mi2c_start(fdelay_device_t *dev)
{
fd_decl_private(dev);
M_SDA_OUT(0);
M_SCL_OUT(0);
}
static void mi2c_repeat_start(fdelay_device_t *dev)
{
fd_decl_private(dev);
M_SDA_OUT(1);
M_SCL_OUT(1);
M_SDA_OUT(0);
M_SCL_OUT(0);
}
static void mi2c_stop(fdelay_device_t *dev)
{
fd_decl_private(dev);
M_SDA_OUT(0);
M_SCL_OUT(1);
M_SDA_OUT(1);
}
int mi2c_put_byte(fdelay_device_t *dev, unsigned char data)
{
fd_decl_private(dev);
char i;
unsigned char ack;
for (i=0;i<8;i++, data<<=1)
{
M_SDA_OUT(data&0x80);
M_SCL_OUT(1);
M_SCL_OUT(0);
}
M_SDA_OUT(1);
M_SCL_OUT(1);
ack = M_SDA_IN; /* ack: sda is pulled low ->success. */
M_SCL_OUT(0);
M_SDA_OUT(0);
return ack!=0 ? -1 : 0;
}
void mi2c_get_byte(fdelay_device_t *dev, unsigned char *data, int ack)
{
fd_decl_private(dev);
int i;
unsigned char indata = 0;
/* assert: scl is low */
M_SCL_OUT(0);
M_SDA_OUT(1);
for (i=0;i<8;i++)
{
M_SCL_OUT(1);
indata <<= 1;
if ( M_SDA_IN ) indata |= 0x01;
M_SCL_OUT(0);
}
M_SDA_OUT((ack ? 0 : 1));
M_SCL_OUT(1);
M_SCL_OUT(0);
M_SDA_OUT(0);
*data= indata;
}
void mi2c_init(fdelay_device_t *dev)
{
fd_decl_private(dev);
M_SCL_OUT(1);
M_SDA_OUT(1);
}
void mi2c_scan(fdelay_device_t *dev)
{
int i;
for(i=0;i<256;i+=2)
{
mi2c_start(dev);
if(!mi2c_put_byte(dev,i))
dbg("Found device at 0x%x\n", i>>1);
mi2c_stop(dev);
}
}
int eeprom_read(fdelay_device_t *dev, uint8_t i2c_addr, uint32_t offset, uint8_t *buf, size_t size)
{
int i;
unsigned char c;
for(i=0;i<size;i++)
{
mi2c_start(dev);
if(mi2c_put_byte(dev, i2c_addr << 1) < 0)
{
mi2c_stop(dev);
return -1;
}
mi2c_put_byte(dev, (offset >> 8) & 0xff);
mi2c_put_byte(dev, offset & 0xff);
offset++;
mi2c_stop(dev);
mi2c_start(dev);
mi2c_put_byte(dev, (i2c_addr << 1) | 1);
mi2c_get_byte(dev, &c, 0);
//printf("readback: %x\n", c);
*buf++ = c;
mi2c_stop(dev);
}
return size;
}
int eeprom_write(fdelay_device_t *dev, uint8_t i2c_addr, uint32_t offset, uint8_t *buf, size_t size)
{
int i, busy;
for(i=0;i<size;i++)
{
mi2c_start(dev);
if(mi2c_put_byte(dev, i2c_addr << 1) < 0)
{
mi2c_stop(dev);
return -1;
}
mi2c_put_byte(dev, (offset >> 8) & 0xff);
mi2c_put_byte(dev, offset & 0xff);
mi2c_put_byte(dev, *buf++);
offset++;
mi2c_stop(dev);
int64_t ts = get_tics();
do /* wait until the chip becomes ready */
{
mi2c_start(dev);
busy = mi2c_put_byte(dev, i2c_addr << 1);
mi2c_stop(dev);
} while(busy && ((get_tics()-ts) < 1000000));
if((get_tics()-ts) >= 1000000)
{
dbg("%s has timed out, the EEPROM doesn't become ready\n", __FUNCTION__);
return -1;
}
}
return size;
}
#include <stdio.h>
#include "fdelay_lib.h"
#include "fdelay_private.h"
#include "fd_main_regs.h"
#define M_SDA_OUT(x) \
{ \
if(x) \
fd_writel(fd_readl(FD_REG_I2CR) | FD_I2CR_SDA_OUT, FD_REG_I2CR); \
else \
fd_writel(fd_readl(FD_REG_I2CR) & (~FD_I2CR_SDA_OUT), FD_REG_I2CR); \
udelay(10); \
}
#define M_SCL_OUT(x) \
{ \
if(x) \
fd_writel(fd_readl(FD_REG_I2CR) | FD_I2CR_SCL_OUT, FD_REG_I2CR); \
else \
fd_writel(fd_readl(FD_REG_I2CR) & (~FD_I2CR_SCL_OUT), FD_REG_I2CR); \
udelay(10); \
}
#define M_SDA_IN ((fd_readl(FD_REG_I2CR) & FD_I2CR_SDA_IN) ? 1 : 0)
static void mi2c_start(fdelay_device_t *dev)
{
fd_decl_private(dev);
M_SDA_OUT(0);
M_SCL_OUT(0);
}
static void mi2c_repeat_start(fdelay_device_t *dev)
{
fd_decl_private(dev);
M_SDA_OUT(1);
M_SCL_OUT(1);
M_SDA_OUT(0);
M_SCL_OUT(0);
}
static void mi2c_stop(fdelay_device_t *dev)
{
fd_decl_private(dev);
M_SDA_OUT(0);
M_SCL_OUT(1);
M_SDA_OUT(1);
}
int mi2c_put_byte(fdelay_device_t *dev, unsigned char data)
{
fd_decl_private(dev);
char i;
unsigned char ack;
for (i=0;i<8;i++, data<<=1)
{
M_SDA_OUT(data&0x80);
M_SCL_OUT(1);
M_SCL_OUT(0);
}
M_SDA_OUT(1);
M_SCL_OUT(1);
ack = M_SDA_IN; /* ack: sda is pulled low ->success. */
M_SCL_OUT(0);
M_SDA_OUT(0);
return ack!=0 ? -1 : 0;
}
void mi2c_get_byte(fdelay_device_t *dev, unsigned char *data, int ack)
{
fd_decl_private(dev);
int i;
unsigned char indata = 0;
/* assert: scl is low */
M_SCL_OUT(0);
M_SDA_OUT(1);
for (i=0;i<8;i++)
{
M_SCL_OUT(1);
indata <<= 1;
if ( M_SDA_IN ) indata |= 0x01;
M_SCL_OUT(0);
}
M_SDA_OUT((ack ? 0 : 1));
M_SCL_OUT(1);
M_SCL_OUT(0);
M_SDA_OUT(0);
*data= indata;
}
void mi2c_init(fdelay_device_t *dev)
{
fd_decl_private(dev);
M_SCL_OUT(1);
M_SDA_OUT(1);
}
void mi2c_scan(fdelay_device_t *dev)
{
int i;
for(i=0;i<256;i+=2)
{
mi2c_start(dev);
if(!mi2c_put_byte(dev,i))
dbg("Found device at 0x%x\n", i>>1);
mi2c_stop(dev);
}
}
int eeprom_read(fdelay_device_t *dev, uint8_t i2c_addr, uint32_t offset, uint8_t *buf, size_t size)
{
int i;
unsigned char c;
for(i=0;i<size;i++)
{
mi2c_start(dev);
if(mi2c_put_byte(dev, i2c_addr << 1) < 0)
{
mi2c_stop(dev);
return -1;
}
mi2c_put_byte(dev, (offset >> 8) & 0xff);
mi2c_put_byte(dev, offset & 0xff);
offset++;
mi2c_stop(dev);
mi2c_start(dev);
mi2c_put_byte(dev, (i2c_addr << 1) | 1);
mi2c_get_byte(dev, &c, 0);
//printf("readback: %x\n", c);
*buf++ = c;
mi2c_stop(dev);
}
return size;
}
int eeprom_write(fdelay_device_t *dev, uint8_t i2c_addr, uint32_t offset, uint8_t *buf, size_t size)
{
int i, busy;
for(i=0;i<size;i++)
{
mi2c_start(dev);
if(mi2c_put_byte(dev, i2c_addr << 1) < 0)
{
mi2c_stop(dev);
return -1;
}
mi2c_put_byte(dev, (offset >> 8) & 0xff);
mi2c_put_byte(dev, offset & 0xff);
mi2c_put_byte(dev, *buf++);
offset++;
mi2c_stop(dev);
int64_t ts = get_tics();
do /* wait until the chip becomes ready */
{
mi2c_start(dev);
busy = mi2c_put_byte(dev, i2c_addr << 1);
mi2c_stop(dev);
} while(busy && ((get_tics()-ts) < 1000000));
if((get_tics()-ts) >= 1000000)
{
dbg("%s has timed out, the EEPROM doesn't become ready\n", __FUNCTION__);
return -1;
}
}
return size;
}
No preview for this file type
/*
* This header differentiates between kernel-mode and user-mode compilation,
* as loader-ll.c is meant to be used in both contexts.
*/
#ifndef __iomem
#define __iomem /* nothing, for user space */
#endif
extern int loader_low_level(
int fd, /* This is ignored in kernel space */
void __iomem *bar4, /* This is ignored in user space */
const void *data,
int size8);
/* 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
};
/* The following part implements a different access rule for user and kernel */
#include <stdio.h>
#include <stdint.h>
#include <sys/ioctl.h>
#include <errno.h>
static inline void lll_write(int fd, void __iomem *bar4, uint32_t val, int reg)
{
*(volatile uint32_t *)(bar4+reg) = val;
}
static inline uint32_t lll_read(int fd, void __iomem *bar4, int reg)
{
return *(volatile uint32_t *)(bar4 + reg);
}
#define KERN_ERR /* nothing */
#define printk(format, ...) fprintf (stderr, format, ## __VA_ARGS__)
/*
* This header differentiates between kernel-mode and user-mode compilation,
* as loader-ll.c is meant to be used in both contexts.
*/
#ifndef __iomem
#define __iomem /* nothing, for user space */
#endif
extern int loader_low_level(
int fd, /* This is ignored in kernel space */
void __iomem *bar4, /* This is ignored in user space */
const void *data,
int size8);
/* 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
};
/* The following part implements a different access rule for user and kernel */
#include <stdio.h>
#include <stdint.h>
#include <sys/ioctl.h>
#include <errno.h>
static inline void lll_write(int fd, void __iomem *bar4, uint32_t val, int reg)
{
*(volatile uint32_t *)(bar4+reg) = val;
}
static inline uint32_t lll_read(int fd, void __iomem *bar4, int reg)
{
return *(volatile uint32_t *)(bar4 + reg);
}
#define KERN_ERR /* nothing */
#define printk(format, ...) fprintf (stderr, format, ## __VA_ARGS__)
/*
* A tool to program our soft-core (LM32) within the SPEC.
*
* Alessandro Rubini 2012 for CERN, GPLv2 or later.
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <getopt.h>
#include "speclib.h"
int main(int argc, char **argv)
{
int bus = -1, dev_fn = -1, c;
uint32_t lm32_base = 0x80000;
void *card;
while ((c = getopt (argc, argv, "b:d:c:")) != -1)
{
switch(c)
{
case 'b':
sscanf(optarg, "%i", &bus);
break;
case 'd':
sscanf(optarg, "%i", &dev_fn);
break;
case 'c':
sscanf(optarg, "%i", &lm32_base);
break;
default:
fprintf(stderr,
"Use: \"%s [-b bus] [-d devfn] [-c lm32 base address] <lm32_program.bin>\"\n", argv[0]);
fprintf(stderr,
"By default, the first available SPEC is used and the LM32 is assumed at 0x%x.\n", lm32_base);
exit(1);
}
}
if (optind >= argc) {
fprintf(stderr, "Expected binary name after options.\n");
exit(1);
}
card = spec_open(bus, dev_fn);
if(!card)
{
fprintf(stderr, "Can't detect a SPEC card under the given adress. Make sure a SPEC card is present in your PC and the driver is loaded.\n");
exit(1);
}
if(spec_load_lm32(card, argv[optind], lm32_base) < 0)
{
fprintf(stderr, "Loader failure.\n");
exit(1);
}
spec_close(card);
exit (0);
}
/*
* A tool to program our soft-core (LM32) within the SPEC.
*
* Alessandro Rubini 2012 for CERN, GPLv2 or later.
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <getopt.h>
#include "speclib.h"
int main(int argc, char **argv)
{
int bus = -1, dev_fn = -1, c;
uint32_t lm32_base = 0x80000;
void *card;
while ((c = getopt (argc, argv, "b:d:c:")) != -1)
{
switch(c)
{
case 'b':
sscanf(optarg, "%i", &bus);
break;
case 'd':
sscanf(optarg, "%i", &dev_fn);
break;
case 'c':
sscanf(optarg, "%i", &lm32_base);
break;
default:
fprintf(stderr,
"Use: \"%s [-b bus] [-d devfn] [-c lm32 base address] <lm32_program.bin>\"\n", argv[0]);
fprintf(stderr,
"By default, the first available SPEC is used and the LM32 is assumed at 0x%x.\n", lm32_base);
exit(1);
}
}
if (optind >= argc) {
fprintf(stderr, "Expected binary name after options.\n");
exit(1);
}
card = spec_open(bus, dev_fn);
if(!card)
{
fprintf(stderr, "Can't detect a SPEC card under the given adress. Make sure a SPEC card is present in your PC and the driver is loaded.\n");
exit(1);
}
if(spec_load_lm32(card, argv[optind], lm32_base) < 0)
{
fprintf(stderr, "Loader failure.\n");
exit(1);
}
spec_close(card);
exit (0);
}
/*
* A tool to program the FPGA within the SPEC.
*
* Alessandro Rubini 2012 for CERN, GPLv2 or later.
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <getopt.h>
#include "speclib.h"
int main(int argc, char **argv)
{
int bus = -1, dev_fn = -1, c;
void *card;
while ((c = getopt (argc, argv, "b:d:")) != -1)
{
switch(c)
{
case 'b':
sscanf(optarg, "%i", &bus);
break;
case 'd':
sscanf(optarg, "%i", &dev_fn);
break;
default:
fprintf(stderr,
"Use: \"%s [-b bus] [-d devfn] <fpga_bitstream.bin>\"\n", argv[0]);
fprintf(stderr,
"By default, the first available SPEC is used.\n");
exit(1);
}
}
if (optind >= argc) {
fprintf(stderr, "Expected binary name after options.\n");
exit(1);
}
card = spec_open(bus, dev_fn);
if(!card)
{
fprintf(stderr, "Can't detect a SPEC card under the given adress. Make sure a SPEC card is present in your PC and the driver is loaded.\n");
exit(1);
}
if(spec_load_bitstream(card, argv[optind]) < 0)
{
fprintf(stderr, "Loader failure.\n");
exit(1);
}
spec_close(card);
exit (0);
}
/*
* A tool to program the FPGA within the SPEC.
*
* Alessandro Rubini 2012 for CERN, GPLv2 or later.
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <getopt.h>
#include "speclib.h"
int main(int argc, char **argv)
{
int bus = -1, dev_fn = -1, c;
void *card;
while ((c = getopt (argc, argv, "b:d:")) != -1)
{
switch(c)
{
case 'b':
sscanf(optarg, "%i", &bus);
break;
case 'd':
sscanf(optarg, "%i", &dev_fn);
break;
default:
fprintf(stderr,
"Use: \"%s [-b bus] [-d devfn] <fpga_bitstream.bin>\"\n", argv[0]);
fprintf(stderr,
"By default, the first available SPEC is used.\n");
exit(1);
}
}
if (optind >= argc) {
fprintf(stderr, "Expected binary name after options.\n");
exit(1);
}
card = spec_open(bus, dev_fn);
if(!card)
{
fprintf(stderr, "Can't detect a SPEC card under the given adress. Make sure a SPEC card is present in your PC and the driver is loaded.\n");
exit(1);
}
if(spec_load_bitstream(card, argv[optind]) < 0)
{
fprintf(stderr, "Loader failure.\n");
exit(1);
}
spec_close(card);
exit (0);
}
/* A simple console for accessing the SPEC virtual UART (i.e. for communicating with the WR Core shell
from a Linux terminal. */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <termios.h>
#include <string.h>
#include <sys/signal.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <getopt.h>
#include <errno.h>
#include "speclib.h"
static void *card;
static int transfer_byte(int from, int is_control) {
char c;
int ret;
do {
ret = read(from, &c, 1);
} while (ret < 0 && errno == EINTR);
if(ret == 1) {
if(is_control) {
if(c == '\x01') { // C-a
return -1;
}
}
spec_vuart_tx(card, &c, 1);
} else {
fprintf(stderr, "\nnothing to read. probably port disconnected.\n");
return -2;
}
return 0;
}
void term_main(int keep_term)
{
struct termios oldkey, newkey; //place tor old and new port settings for keyboard teletype
int need_exit = 0;
fprintf(stderr, "[press C-a to exit]\n");
if(!keep_term) {
tcgetattr(STDIN_FILENO,&oldkey);
newkey.c_cflag = B9600 | CS8 | CLOCAL | CREAD;
newkey.c_iflag = IGNPAR;
newkey.c_oflag = 0;
newkey.c_lflag = 0;
newkey.c_cc[VMIN]=1;
newkey.c_cc[VTIME]=0;
tcflush(STDIN_FILENO, TCIFLUSH);
tcsetattr(STDIN_FILENO,TCSANOW,&newkey);
}
while(!need_exit) {
fd_set fds;
int ret;
char rx;
struct timeval tv = {0, 10000};
FD_ZERO(&fds);
FD_SET(STDIN_FILENO, &fds);
ret = select(STDIN_FILENO+1, &fds, NULL, NULL, &tv);
if(ret == -1) {
perror("select");
} else if (ret > 0) {
if(FD_ISSET(STDIN_FILENO, &fds)) {
need_exit = transfer_byte(STDIN_FILENO, 1);
}
}
while((spec_vuart_rx(card, &rx, 1)) == 1)
fprintf(stderr,"%c", rx);
}
if(!keep_term)
tcsetattr(STDIN_FILENO,TCSANOW,&oldkey);
}
int main(int argc, char **argv)
{
int bus = -1, dev_fn = -1, c;
uint32_t vuart_base = 0xe0500;
int keep_term = 0;
while ((c = getopt (argc, argv, "b:d:u:k")) != -1)
{
switch(c)
{
case 'b':
sscanf(optarg, "%i", &bus);
break;
case 'd':
sscanf(optarg, "%i", &dev_fn);
break;
case 'u':
sscanf(optarg, "%i", &vuart_base);
break;
case 'k':
keep_term = 1;
break;
default:
fprintf(stderr,
"Use: \"%s [-b bus] [-d devfn] [-u VUART base] [-k]\"\n", argv[0]);
fprintf(stderr,
"By default, the first available SPEC is used and the VUART is assumed at 0x%x.\n \
-k option keeps the terminal config unchanged.", vuart_base);
exit(1);
}
}
card = spec_open(bus, dev_fn);
if(!card)
{
fprintf(stderr, "Can't detect a SPEC card under the given adress. Make sure a SPEC card is present in your PC and the driver is loaded.\n");
exit(1);
}
spec_vuart_init(card, vuart_base);
term_main(keep_term);
spec_close(card);
return 0;
}
/* A simple console for accessing the SPEC virtual UART (i.e. for communicating with the WR Core shell
from a Linux terminal. */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <termios.h>
#include <string.h>
#include <sys/signal.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <getopt.h>
#include <errno.h>
#include "speclib.h"
static void *card;
static int transfer_byte(int from, int is_control) {
char c;
int ret;
do {
ret = read(from, &c, 1);
} while (ret < 0 && errno == EINTR);
if(ret == 1) {
if(is_control) {
if(c == '\x01') { // C-a
return -1;
}
}
spec_vuart_tx(card, &c, 1);
} else {
fprintf(stderr, "\nnothing to read. probably port disconnected.\n");
return -2;
}
return 0;
}
void term_main(int keep_term)
{
struct termios oldkey, newkey; //place tor old and new port settings for keyboard teletype
int need_exit = 0;
fprintf(stderr, "[press C-a to exit]\n");
if(!keep_term) {
tcgetattr(STDIN_FILENO,&oldkey);
newkey.c_cflag = B9600 | CS8 | CLOCAL | CREAD;
newkey.c_iflag = IGNPAR;
newkey.c_oflag = 0;
newkey.c_lflag = 0;
newkey.c_cc[VMIN]=1;
newkey.c_cc[VTIME]=0;
tcflush(STDIN_FILENO, TCIFLUSH);
tcsetattr(STDIN_FILENO,TCSANOW,&newkey);
}
while(!need_exit) {
fd_set fds;
int ret;
char rx;
struct timeval tv = {0, 10000};
FD_ZERO(&fds);
FD_SET(STDIN_FILENO, &fds);
ret = select(STDIN_FILENO+1, &fds, NULL, NULL, &tv);
if(ret == -1) {
perror("select");
} else if (ret > 0) {
if(FD_ISSET(STDIN_FILENO, &fds)) {
need_exit = transfer_byte(STDIN_FILENO, 1);
}
}
while((spec_vuart_rx(card, &rx, 1)) == 1)
fprintf(stderr,"%c", rx);
}
if(!keep_term)
tcsetattr(STDIN_FILENO,TCSANOW,&oldkey);
}
int main(int argc, char **argv)
{
int bus = -1, dev_fn = -1, c;
uint32_t vuart_base = 0xe0500;
int keep_term = 0;
while ((c = getopt (argc, argv, "b:d:u:k")) != -1)
{
switch(c)
{
case 'b':
sscanf(optarg, "%i", &bus);
break;
case 'd':
sscanf(optarg, "%i", &dev_fn);
break;
case 'u':
sscanf(optarg, "%i", &vuart_base);
break;
case 'k':
keep_term = 1;
break;
default:
fprintf(stderr,
"Use: \"%s [-b bus] [-d devfn] [-u VUART base] [-k]\"\n", argv[0]);
fprintf(stderr,
"By default, the first available SPEC is used and the VUART is assumed at 0x%x.\n \
-k option keeps the terminal config unchanged.", vuart_base);
exit(1);
}
}
card = spec_open(bus, dev_fn);
if(!card)
{
fprintf(stderr, "Can't detect a SPEC card under the given adress. Make sure a SPEC card is present in your PC and the driver is loaded.\n");
exit(1);
}
spec_vuart_init(card, vuart_base);
term_main(keep_term);
spec_close(card);
return 0;
}
#ifndef __SPECLIB_H
#define __SPECLIB_H
#include <stdint.h>
/* 'Opens' the SPEC card at PCI bus [bus], device/function [dev].
Returns a handle to the card or NULL in case of failure. */
void *spec_open(int bus, int dev);
/* Closes the SPEC handle [card] */
void spec_close(void *card);
/* Loads the FPGA bitstream into card [card] from file [filename].
Returns 0 on success. */
int spec_load_bitstream(void *card, const char *filename);
/* Loads the WRC LM32 firmware into card [card] from file [filename]. starting at
address [base_addr]. Returns 0 on success.
WARNING: using improper base address/FPGA firmware will freeze the computer. */
int spec_load_lm32(void *card, const char *filename, uint32_t base_addr);
/* Raw I/O to BAR4 (Wishbone) */
void spec_writel(void *card, uint32_t data, uint32_t addr);
uint32_t spec_readl(void *card, uint32_t addr);
/* Initializes a virtual UART at base address [base_addr]. */
int spec_vuart_init(void *card, uint32_t base_addr);
/* Virtual uart Rx (VUART->Host) and Tx (Host->VUART) functions */
size_t spec_vuart_rx(void *card, char *buffer, size_t size);
size_t spec_vuart_tx(void *card, char *buffer, size_t size);
#endif
#ifndef __SPECLIB_H
#define __SPECLIB_H
#include <stdint.h>
/* 'Opens' the SPEC card at PCI bus [bus], device/function [dev].
Returns a handle to the card or NULL in case of failure. */
void *spec_open(int bus, int dev);
/* Closes the SPEC handle [card] */
void spec_close(void *card);
/* Loads the FPGA bitstream into card [card] from file [filename].
Returns 0 on success. */
int spec_load_bitstream(void *card, const char *filename);
/* Loads the WRC LM32 firmware into card [card] from file [filename]. starting at
address [base_addr]. Returns 0 on success.
WARNING: using improper base address/FPGA firmware will freeze the computer. */
int spec_load_lm32(void *card, const char *filename, uint32_t base_addr);
/* Raw I/O to BAR4 (Wishbone) */
void spec_writel(void *card, uint32_t data, uint32_t addr);
uint32_t spec_readl(void *card, uint32_t addr);
/* Initializes a virtual UART at base address [base_addr]. */
int spec_vuart_init(void *card, uint32_t base_addr);
/* Virtual uart Rx (VUART->Host) and Tx (Host->VUART) functions */
size_t spec_vuart_rx(void *card, char *buffer, size_t size);
size_t spec_vuart_tx(void *card, char *buffer, size_t size);
#endif
/*
* A tool to read SPEC-internal memory (only BAR0)
*
* Alessandro Rubini 2012 for CERN, GPLv2 or later.
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/mman.h>
#include "spec-tools.h"
int main(int argc, char **argv)
{
int i, fd, bar = BASE_BAR0;
uint32_t base, *ptr;
uint32_t uarg[3];
void *map_base;
char *end;
if (argc > 1 && !strcmp(argv[1], "-g")) {
bar = BASE_BAR4;
argv[1] = argv[0];
argc--; argv++;
}
if (argc < 2 || argc > 3) {
fprintf(stderr,
"Use: \"%s [-g] <offset> [<value>]\" "
"(-g selects gennum memory, I/O is 32 bits)\n",
argv[0]);
exit(1);
}
if((fd = open("/dev/mem", O_RDWR | O_SYNC)) < 0) {
fprintf(stderr, "%s: open(/dev/mem): %s\n", argv[0],
strerror(errno));
exit(1);
}
base = spec_get_base(bar);
if (base == (typeof(base))-1) {
fprintf(stderr, "%s: spec_get_base(): %s\n", argv[0],
strerror(errno));
exit(1);
}
map_base = mmap(0, 1024 * 1024, /* gennum's bar 0 is 1M */
PROT_READ | PROT_WRITE, MAP_SHARED, fd, base);
if(map_base == (void *) -1) {
fprintf(stderr, "%s: mmap(/dev/mem): %s\n", argv[0],
strerror(errno));
exit(1);
}
for (i = 1; i < argc; i++) {
uarg[i] = strtol(argv[i], &end, 16);
if (end && *end) {
fprintf(stderr, "%s: \"%s\" is not an hex number\n",
argv[0], argv[i]);
exit(1);
}
}
if (uarg[1] & 3) {
fprintf(stderr, "%s: address \"%s\" not multiple of 4\n",
argv[0], argv[1]);
exit(1);
}
ptr = map_base + uarg[1];
/* by default, operate quietly (only report read value) */
if (argc == 2) {
uarg[2] = *ptr;
if (!getenv("VERBOSE"))
printf("%08x\n", uarg[2]);
} else {
*ptr = uarg[2];
}
/* be verbose, if so requested */
if (getenv("VERBOSE")) {
if (argc == 2)
printf("%08x == %08x\n", uarg[1], uarg[2]);
else
printf("%08x := %08x\n", uarg[1], uarg[2]);
}
exit (0);
}
/*
* A tool to read SPEC-internal memory (only BAR0)
*
* Alessandro Rubini 2012 for CERN, GPLv2 or later.
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/mman.h>
#include "spec-tools.h"
int main(int argc, char **argv)
{
int i, fd, bar = BASE_BAR0;
uint32_t base, *ptr;
uint32_t uarg[3];
void *map_base;
char *end;
if (argc > 1 && !strcmp(argv[1], "-g")) {
bar = BASE_BAR4;
argv[1] = argv[0];
argc--; argv++;
}
if (argc < 2 || argc > 3) {
fprintf(stderr,
"Use: \"%s [-g] <offset> [<value>]\" "
"(-g selects gennum memory, I/O is 32 bits)\n",
argv[0]);
exit(1);
}
if((fd = open("/dev/mem", O_RDWR | O_SYNC)) < 0) {
fprintf(stderr, "%s: open(/dev/mem): %s\n", argv[0],
strerror(errno));
exit(1);
}
base = spec_get_base(bar);
if (base == (typeof(base))-1) {
fprintf(stderr, "%s: spec_get_base(): %s\n", argv[0],
strerror(errno));
exit(1);
}
map_base = mmap(0, 1024 * 1024, /* gennum's bar 0 is 1M */
PROT_READ | PROT_WRITE, MAP_SHARED, fd, base);
if(map_base == (void *) -1) {
fprintf(stderr, "%s: mmap(/dev/mem): %s\n", argv[0],
strerror(errno));
exit(1);
}
for (i = 1; i < argc; i++) {
uarg[i] = strtol(argv[i], &end, 16);
if (end && *end) {
fprintf(stderr, "%s: \"%s\" is not an hex number\n",
argv[0], argv[i]);
exit(1);
}
}
if (uarg[1] & 3) {
fprintf(stderr, "%s: address \"%s\" not multiple of 4\n",
argv[0], argv[1]);
exit(1);
}
ptr = map_base + uarg[1];
/* by default, operate quietly (only report read value) */
if (argc == 2) {
uarg[2] = *ptr;
if (!getenv("VERBOSE"))
printf("%08x\n", uarg[2]);
} else {
*ptr = uarg[2];
}
/* be verbose, if so requested */
if (getenv("VERBOSE")) {
if (argc == 2)
printf("%08x == %08x\n", uarg[1], uarg[2]);
else
printf("%08x := %08x\n", uarg[1], uarg[2]);
}
exit (0);
}
/*
Register definitions for slave core: Simple Wishbone UART
* File : wb_uart.h
* Author : auto-generated by wbgen2 from simple_uart_wb.wb
* Created : Thu May 3 17:36:38 2012
* Standard : ANSI C
THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE simple_uart_wb.wb
DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
*/
#ifndef __WBGEN2_REGDEFS_SIMPLE_UART_WB_WB
#define __WBGEN2_REGDEFS_SIMPLE_UART_WB_WB
#include <inttypes.h>
#if defined( __GNUC__)
#define PACKED __attribute__ ((packed))
#else
#error "Unsupported compiler?"
#endif
#ifndef __WBGEN2_MACROS_DEFINED__
#define __WBGEN2_MACROS_DEFINED__
#define WBGEN2_GEN_MASK(offset, size) (((1<<(size))-1) << (offset))
#define WBGEN2_GEN_WRITE(value, offset, size) (((value) & ((1<<(size))-1)) << (offset))
#define WBGEN2_GEN_READ(reg, offset, size) (((reg) >> (offset)) & ((1<<(size))-1))
#define WBGEN2_SIGN_EXTEND(value, bits) (((value) & (1<<bits) ? ~((1<<(bits))-1): 0 ) | (value))
#endif
/* definitions for register: Status Register */
/* definitions for field: TX busy in reg: Status Register */
#define UART_SR_TX_BUSY WBGEN2_GEN_MASK(0, 1)
/* definitions for field: RX ready in reg: Status Register */
#define UART_SR_RX_RDY WBGEN2_GEN_MASK(1, 1)
/* definitions for register: Baudrate control register */
/* definitions for register: Transmit data regsiter */
/* definitions for field: Transmit data in reg: Transmit data regsiter */
#define UART_TDR_TX_DATA_MASK WBGEN2_GEN_MASK(0, 8)
#define UART_TDR_TX_DATA_SHIFT 0
#define UART_TDR_TX_DATA_W(value) WBGEN2_GEN_WRITE(value, 0, 8)
#define UART_TDR_TX_DATA_R(reg) WBGEN2_GEN_READ(reg, 0, 8)
/* definitions for register: Receive data regsiter */
/* definitions for field: Received data in reg: Receive data regsiter */
#define UART_RDR_RX_DATA_MASK WBGEN2_GEN_MASK(0, 8)
#define UART_RDR_RX_DATA_SHIFT 0
#define UART_RDR_RX_DATA_W(value) WBGEN2_GEN_WRITE(value, 0, 8)
#define UART_RDR_RX_DATA_R(reg) WBGEN2_GEN_READ(reg, 0, 8)
/* definitions for register: Host VUART Tx register */
/* definitions for field: TX Data in reg: Host VUART Tx register */
#define UART_HOST_TDR_DATA_MASK WBGEN2_GEN_MASK(0, 8)
#define UART_HOST_TDR_DATA_SHIFT 0
#define UART_HOST_TDR_DATA_W(value) WBGEN2_GEN_WRITE(value, 0, 8)
#define UART_HOST_TDR_DATA_R(reg) WBGEN2_GEN_READ(reg, 0, 8)
/* definitions for field: TX Ready in reg: Host VUART Tx register */
#define UART_HOST_TDR_RDY WBGEN2_GEN_MASK(8, 1)
/* definitions for register: Host VUART Rx register */
/* definitions for field: RX Data in reg: Host VUART Rx register */
#define UART_HOST_RDR_DATA_MASK WBGEN2_GEN_MASK(0, 8)
#define UART_HOST_RDR_DATA_SHIFT 0
#define UART_HOST_RDR_DATA_W(value) WBGEN2_GEN_WRITE(value, 0, 8)
#define UART_HOST_RDR_DATA_R(reg) WBGEN2_GEN_READ(reg, 0, 8)
/* definitions for field: RX Ready in reg: Host VUART Rx register */
#define UART_HOST_RDR_RDY WBGEN2_GEN_MASK(8, 1)
/* definitions for field: RX FIFO Count in reg: Host VUART Rx register */
#define UART_HOST_RDR_COUNT_MASK WBGEN2_GEN_MASK(9, 16)
#define UART_HOST_RDR_COUNT_SHIFT 9
#define UART_HOST_RDR_COUNT_W(value) WBGEN2_GEN_WRITE(value, 9, 16)
#define UART_HOST_RDR_COUNT_R(reg) WBGEN2_GEN_READ(reg, 9, 16)
#define UART_REG_SR 0x0
#define UART_REG_HOST_TDR 0x10
#define UART_REG_HOST_RDR 0x14
#endif
/*
Register definitions for slave core: Simple Wishbone UART
* File : wb_uart.h
* Author : auto-generated by wbgen2 from simple_uart_wb.wb
* Created : Thu Aug 9 10:31:41 2012
* Standard : ANSI C
THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE simple_uart_wb.wb
DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
*/
#ifndef __WBGEN2_REGDEFS_SIMPLE_UART_WB_WB
#define __WBGEN2_REGDEFS_SIMPLE_UART_WB_WB
#include <inttypes.h>
#if defined( __GNUC__)
#define PACKED __attribute__ ((packed))
#else
#error "Unsupported compiler?"
#endif
#ifndef __WBGEN2_MACROS_DEFINED__
#define __WBGEN2_MACROS_DEFINED__
#define WBGEN2_GEN_MASK(offset, size) (((1<<(size))-1) << (offset))
#define WBGEN2_GEN_WRITE(value, offset, size) (((value) & ((1<<(size))-1)) << (offset))
#define WBGEN2_GEN_READ(reg, offset, size) (((reg) >> (offset)) & ((1<<(size))-1))
#define WBGEN2_SIGN_EXTEND(value, bits) (((value) & (1<<bits) ? ~((1<<(bits))-1): 0 ) | (value))
#endif
/* definitions for register: Status Register */
/* definitions for field: TX busy in reg: Status Register */
#define UART_SR_TX_BUSY WBGEN2_GEN_MASK(0, 1)
/* definitions for field: RX ready in reg: Status Register */
#define UART_SR_RX_RDY WBGEN2_GEN_MASK(1, 1)
/* definitions for register: Baudrate control register */
/* definitions for register: Transmit data regsiter */
/* definitions for field: Transmit data in reg: Transmit data regsiter */
#define UART_TDR_TX_DATA_MASK WBGEN2_GEN_MASK(0, 8)
#define UART_TDR_TX_DATA_SHIFT 0
#define UART_TDR_TX_DATA_W(value) WBGEN2_GEN_WRITE(value, 0, 8)
#define UART_TDR_TX_DATA_R(reg) WBGEN2_GEN_READ(reg, 0, 8)
/* definitions for register: Receive data regsiter */
/* definitions for field: Received data in reg: Receive data regsiter */
#define UART_RDR_RX_DATA_MASK WBGEN2_GEN_MASK(0, 8)
#define UART_RDR_RX_DATA_SHIFT 0
#define UART_RDR_RX_DATA_W(value) WBGEN2_GEN_WRITE(value, 0, 8)
#define UART_RDR_RX_DATA_R(reg) WBGEN2_GEN_READ(reg, 0, 8)
/* definitions for register: Host VUART Tx register */
/* definitions for field: TX Data in reg: Host VUART Tx register */
#define UART_HOST_TDR_DATA_MASK WBGEN2_GEN_MASK(0, 8)
#define UART_HOST_TDR_DATA_SHIFT 0
#define UART_HOST_TDR_DATA_W(value) WBGEN2_GEN_WRITE(value, 0, 8)
#define UART_HOST_TDR_DATA_R(reg) WBGEN2_GEN_READ(reg, 0, 8)
/* definitions for field: TX Ready in reg: Host VUART Tx register */
#define UART_HOST_TDR_RDY WBGEN2_GEN_MASK(8, 1)
/* definitions for register: Host VUART Rx register */
/* definitions for field: RX Data in reg: Host VUART Rx register */
#define UART_HOST_RDR_DATA_MASK WBGEN2_GEN_MASK(0, 8)
#define UART_HOST_RDR_DATA_SHIFT 0
#define UART_HOST_RDR_DATA_W(value) WBGEN2_GEN_WRITE(value, 0, 8)
#define UART_HOST_RDR_DATA_R(reg) WBGEN2_GEN_READ(reg, 0, 8)
/* definitions for field: RX Ready in reg: Host VUART Rx register */
#define UART_HOST_RDR_RDY WBGEN2_GEN_MASK(8, 1)
/* definitions for field: RX FIFO Count in reg: Host VUART Rx register */
#define UART_HOST_RDR_COUNT_MASK WBGEN2_GEN_MASK(9, 16)
#define UART_HOST_RDR_COUNT_SHIFT 9
#define UART_HOST_RDR_COUNT_W(value) WBGEN2_GEN_WRITE(value, 9, 16)
#define UART_HOST_RDR_COUNT_R(reg) WBGEN2_GEN_READ(reg, 9, 16)
#define UART_REG_SR 0x0
#define UART_REG_HOST_TDR 0x10
#define UART_REG_HOST_RDR 0x14
#endif
......@@ -4,6 +4,8 @@
#include "spec/tools/speclib.h"
#include "fdelay_lib.h"
void printk(){}
static void fd_spec_writel(void *priv, uint32_t data, uint32_t addr)
{
......
#! /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)
This diff is collapsed.
This diff is collapsed.
#! /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
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -94,8 +94,7 @@ struct fmc_oem_data {
uint8_t p1_b_nsig;
uint8_t p2_a_nsig;
uint8_t p2_b_nsig;
uint8_t p1_gbt_ntran;
uint8_t p2_gbt_ntran;
uint8_t p1_p2_gbt_ntran;
uint8_t max_clock;
};
......
# This is an example config file, that can be used to build a filesystem
# from this very directory. Please note that gensdbfs doesn't look for
# config files in subdirectories but only in the tol-level one.
.
vendor = 0x000000000000CE42
device = 0xf19ede1a
position = 0x100
IPMI-FRU
position = 0
calibration
maxsize = 0x6e
name
maxsize = 0x20
\ No newline at end of file
fdelay
\ No newline at end of file
This diff is collapsed.
......@@ -105,7 +105,7 @@ def main (card=None, default_directory='.',suite=None):
if(error[0] != 0):
print("One or both LEDs not switching ON. Check for soldering or connection problem, grounded control line")
if(error[1] != 0):
print("One or both LEDs not switching OFF. Check for short-cut.")
print("One or both LEDs not switching OFF. Check for short circuits.")
raise PtsError('An error occurred during LEDs test, check log for details.')
else:
print('LEDs are working ok.')
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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