Commit 1a084cab authored by Evangelia Gousiou's avatar Evangelia Gousiou

more cleanup; removed fmc-delay folder, updated fmceeprom files; still not stable though

parent 7a8148c5
From 39f005c1b8d78075841eef18e8a5e4bb78f3c611 Mon Sep 17 00:00:00 2001
From: user <user@baraka.(none)>
Date: Thu, 19 Apr 2012 15:31:57 +0200
Subject: [PATCH 1/2] Add pulse generator support in the pyhton library.
Modify C library for multiple SPEC board control from Python.
---
software/include/fdelay_lib.h | 2 +-
software/include/rr_io.h | 1 +
software/lib/fdelay_bus.c | 4 +-
software/lib/fdelay_cal.c | 2 +-
software/lib/fdelay_lib.c | 7 ++--
software/lib/rr_io.c | 6 ++++
software/python/fdelay_lib.py | 66 ++++++++++++++++++++++++++++-------------
7 files changed, 60 insertions(+), 28 deletions(-)
diff --git a/software/include/fdelay_lib.h b/software/include/fdelay_lib.h
index e3da3f7..e11e009 100644
--- a/software/include/fdelay_lib.h
+++ b/software/include/fdelay_lib.h
@@ -51,7 +51,7 @@ PUBLIC API
*/
-fdelay_device_t *fdelay_create_rawrabbit(uint32_t base_addr);
+fdelay_device_t *fdelay_create_rawrabbit(int fd, uint32_t base_addr);
fdelay_device_t *fdelay_create_minibone(char *iface, char *mac_addr, uint32_t base_addr);
fdelay_time_t fdelay_from_picos(const uint64_t ps);
diff --git a/software/include/rr_io.h b/software/include/rr_io.h
index 713d7bf..f59ebbd 100644
--- a/software/include/rr_io.h
+++ b/software/include/rr_io.h
@@ -4,6 +4,7 @@
#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);
diff --git a/software/lib/fdelay_bus.c b/software/lib/fdelay_bus.c
index c79790f..b9976ee 100644
--- a/software/lib/fdelay_bus.c
+++ b/software/lib/fdelay_bus.c
@@ -36,10 +36,10 @@ uint32_t d = mbn_readl(priv, addr >> 2);
return d;
}
-fdelay_device_t *fdelay_create_rawrabbit(uint32_t base_addr)
+fdelay_device_t *fdelay_create_rawrabbit(int fd, uint32_t base_addr)
{
fdelay_device_t *dev = malloc(sizeof(fdelay_device_t));
- rr_init(RR_DEVSEL_UNUSED, RR_DEVSEL_UNUSED);
+ rr_bind(fd);
dev->writel = my_rr_writel;
dev->readl = my_rr_readl;
dev->base_addr = base_addr;
diff --git a/software/lib/fdelay_cal.c b/software/lib/fdelay_cal.c
index 74adc50..afae401 100644
--- a/software/lib/fdelay_cal.c
+++ b/software/lib/fdelay_cal.c
@@ -71,7 +71,7 @@ main()
{
fdelay_device_t *dev = malloc(sizeof(fdelay_device_t));
- rr_init();
+ rr_init(RR_DEVSEL_UNUSED, RR_DEVSEL_UNUSED);
dev->writel = my_writel;
dev->readl = my_readl;
diff --git a/software/lib/fdelay_lib.c b/software/lib/fdelay_lib.c
index 3dc5d72..8c6eafd 100644
--- a/software/lib/fdelay_lib.c
+++ b/software/lib/fdelay_lib.c
@@ -1224,9 +1224,10 @@ int fdelay_configure_pulse_gen(fdelay_device_t *dev, int channel, int enable, fd
start = t_start;
end = ts_add(start, fdelay_from_picos(width_ps));
- delta = fdelay_from_picos(delta_ps);
+ delta = fdelay_from_picos(delta_ps);
-// printf("Start: %lld: %d:%d\n", start.utc, start.coarse, start.frac);
+ printf("Start: %lld: %d:%d\n", start.utc, start.coarse, start.frac);
+ printf("width: %lld delta: %lld rep: %d\n", width_ps, delta_ps, rep_count);
chan_writel(hw->frr_cur[channel-1], FD_REG_FRR);
@@ -1390,4 +1391,4 @@ int fd_update_spll(fdelay_device_t *dev)
}
}
-#endif
\ No newline at end of file
+#endif
diff --git a/software/lib/rr_io.c b/software/lib/rr_io.c
index 99e39b0..75be14e 100644
--- a/software/lib/rr_io.c
+++ b/software/lib/rr_io.c
@@ -18,6 +18,12 @@
static int fd;
+int rr_bind(int a_fd)
+{
+ fd = a_fd;
+ return 0;
+}
+
int rr_init(int bus, int devfn)
{
struct rr_devsel devsel;
diff --git a/software/python/fdelay_lib.py b/software/python/fdelay_lib.py
index edda05f..0e8881b 100755
--- a/software/python/fdelay_lib.py
+++ b/software/python/fdelay_lib.py
@@ -3,12 +3,14 @@
from ctypes import *
import sys
import re
+import os
class fd_timestamp(Structure):
- _fields_ = [("utc", c_ulong),
- ("coarse", c_ulong),
- ("frac", c_ulong),
- ("seq_id", c_ushort)]
+ _fields_ = [("utc", c_ulonglong),
+ ("coarse", c_ulong),
+ ("frac", c_ulong),
+ ("seq_id", c_ushort),
+ ("channel", c_int)]
def nsecs(self):
return (float(self.frac) * 8000.0 / 4096.0 + float(self.coarse) * 8000.0) / 1000.0;
@@ -21,6 +23,8 @@ class fd_timestamp(Structure):
class FineDelay:
+ BASE_ADDR = 0x84000
+
FREE_RUNNING = 0x10
WR_OFFLINE = 0x8
WR_READY = 0x1
@@ -29,46 +33,66 @@ class FineDelay:
SYNC_LOCAL = 0x1
SYNC_WR = 0x2
- def __init__(self, dev_path):
+ def __init__(self, fd):
+ cwd = os.path.dirname(__file__)
+ self.fdelay = CDLL(cwd+'/../lib/libfinedelay.so')
+ self.handle = c_voidp(self.fdelay.fdelay_create_rawrabbit(c_int(fd), c_ulong(self.BASE_ADDR)));
+ """
s = re.split("\/", dev_path)
- self.fd = CDLL('../lib/libfinedelay.so')
+ self.fdelay = CDLL('../lib/libfinedelay.so')
if(s[0] == "local"):
print("Initializing local at %x" % int(s[1], 16))
- self.handle = c_voidp(self.fd.fdelay_create_rawrabbit(int(s[1],16)));
+ self.handle = c_voidp(self.fdelay.fdelay_create_rawrabbit(int(s[1],16)));
elif(s[0] == "minibone"):
print("Initializing minibone at %s [%s]\n" %( s[1], s[2]))
- self.handle = c_voidp(self.fd.fdelay_create_minibone(c_char_p(s[1]), c_char_p(s[2]), int(s[3], 16)));
-
- if(self.fd.fdelay_init(self.handle) < 0):
+ self.handle = c_voidp(self.fdelay.fdelay_create_minibone(c_char_p(s[1]), c_char_p(s[2]), int(s[3], 16)));
+ """
+ if(self.fdelay.fdelay_init(self.handle) < 0):
print ("Init failed..");
# sys.exit(-1)
+
def conf_trigger(self, enable, termination):
- self.fd.fdelay_configure_trigger(self.handle, c_int(enable), c_int(termination))
-
+ self.fdelay.fdelay_configure_trigger(self.handle, c_int(enable), c_int(termination))
+
def conf_output(self, channel, enable, delay, width):
- self.fd.fdelay_configure_output(self.handle, c_int(channel), c_int(enable), c_ulonglong(delay), c_ulonglong(width))
-
+ self.fdelay.fdelay_configure_output(self.handle, c_int(channel), c_int(enable), c_ulonglong(delay), c_ulonglong(width))
+
def conf_readout(self, enable):
- self.fd.fdelay_configure_readout(self.handle, enable)
-
+ self.fdelay.fdelay_configure_readout(self.handle, enable)
+
def conf_sync(self, mode):
- self.fd.fdelay_configure_sync(self.handle, mode)
-
+ self.fdelay.fdelay_configure_sync(self.handle, mode)
+
+ def conf_pulsegen(self, channel, enable, t_start_utc, width, delta, count):
+ t = fd_timestamp(utc=c_ulonglong(t_start_utc), coarse=c_ulong(0))
+ #print "channel:%d enable:%d start_t:%d width:%d delta:%d count:%d"%(channel, enable, t.utc, width, delta, count)
+ self.fdelay.fdelay_configure_pulse_gen(self.handle, c_int(channel), c_int(enable), t,
+ c_ulonglong(width), c_ulonglong(delta), c_int(count))
+
+ def set_time(self, utc, coarse):
+ t = fd_timestamp(utc=c_ulonglong(utc), coarse=c_ulong(coarse))
+ self.fdelay.fdelay_set_time(self.handle, t)
+
+ def get_time(self):
+ t = fd_timestamp()
+ self.fdelay.fdelay_get_time(self.handle, byref(t))
+ return t
+
def get_sync_status(self):
htab = { self.FREE_RUNNING : "oscillator free-running",
self.WR_OFFLINE : "WR core offline",
self.WR_READY : "WR core ready",
self.WR_SYNCING : "Syncing local clock with WR",
self.WR_SYNCED : "Synced with WR" }
-# status = c_int(self.fd.fdelay_get_sync_status(self.handle));
+# status = c_int(self.fdelay.fdelay_get_sync_status(self.handle));
# print("GetSyncStatus %x" % status.value);
return "none"; #htab[status.value]
-
+
def read_ts(self):
buf = (fd_timestamp * 256)();
ptr = pointer(buf)
- n = self.fd.fdelay_read(self.handle, ptr, 256)
+ n = self.fdelay.fdelay_read(self.handle, ptr, 256)
arr = [];
for i in range(0,n):
arr.append(buf[i])
--
1.7.4.1
From b5c7ac0bd61db02dd2c37e9c8d21752f6b761812 Mon Sep 17 00:00:00 2001
From: user <user@baraka.(none)>
Date: Wed, 25 Apr 2012 15:37:59 +0200
Subject: [PATCH 2/2] Change pulse generator configuration function in the python lib, allows set start time with 8ns resolution (instead of only UTC).
Remove 4ns of the pulse width in the C library, due to a hardware bug.
---
software/lib/fdelay_lib.c | 14 ++++++++++----
software/python/fdelay_lib.py | 5 +++--
2 files changed, 13 insertions(+), 6 deletions(-)
diff --git a/software/lib/fdelay_lib.c b/software/lib/fdelay_lib.c
index 8c6eafd..b0ab7dc 100644
--- a/software/lib/fdelay_lib.c
+++ b/software/lib/fdelay_lib.c
@@ -1171,7 +1171,8 @@ int fdelay_configure_output(fdelay_device_t *dev, int channel, int enable, int64
delay_ps -= hw->calib.zero_offset[channel-1];
start = fdelay_from_picos(delay_ps);
end = fdelay_from_picos(delay_ps + width_ps);
- delta = fdelay_from_picos(delta_ps);
+ delta = fdelay_from_picos(delta_ps);
+
// printf("Start: %lld: %d:%d\n", start.utc, start.coarse, start.frac);
@@ -1222,12 +1223,17 @@ int fdelay_configure_pulse_gen(fdelay_device_t *dev, int channel, int enable, fd
if(channel < 1 || channel > 4)
return -1;
+
start = t_start;
- end = ts_add(start, fdelay_from_picos(width_ps));
+ end = fdelay_from_picos(fdelay_to_picos(start) + width_ps - 4000);
delta = fdelay_from_picos(delta_ps);
- printf("Start: %lld: %d:%d\n", start.utc, start.coarse, start.frac);
- printf("width: %lld delta: %lld rep: %d\n", width_ps, delta_ps, rep_count);
+ //start = t_start;
+ //end = ts_add(start, fdelay_from_picos(width_ps));
+ //delta = fdelay_from_picos(delta_ps);
+
+ //printf("Start: %lld: %d:%d\n", start.utc, start.coarse, start.frac);
+ //printf("width: %lld delta: %lld rep: %d\n", width_ps, delta_ps, rep_count);
chan_writel(hw->frr_cur[channel-1], FD_REG_FRR);
diff --git a/software/python/fdelay_lib.py b/software/python/fdelay_lib.py
index 0e8881b..8eb2bd3 100755
--- a/software/python/fdelay_lib.py
+++ b/software/python/fdelay_lib.py
@@ -47,6 +47,7 @@ class FineDelay:
print("Initializing minibone at %s [%s]\n" %( s[1], s[2]))
self.handle = c_voidp(self.fdelay.fdelay_create_minibone(c_char_p(s[1]), c_char_p(s[2]), int(s[3], 16)));
"""
+ print "Initialising Fine Delay board..."
if(self.fdelay.fdelay_init(self.handle) < 0):
print ("Init failed..");
# sys.exit(-1)
@@ -64,8 +65,8 @@ class FineDelay:
def conf_sync(self, mode):
self.fdelay.fdelay_configure_sync(self.handle, mode)
- def conf_pulsegen(self, channel, enable, t_start_utc, width, delta, count):
- t = fd_timestamp(utc=c_ulonglong(t_start_utc), coarse=c_ulong(0))
+ def conf_pulsegen(self, channel, enable, t_start_utc, t_start_coarse, width, delta, count):
+ t = fd_timestamp(utc=c_ulonglong(t_start_utc), coarse=c_ulong(t_start_coarse))
#print "channel:%d enable:%d start_t:%d width:%d delta:%d count:%d"%(channel, enable, t.utc, width, delta, count)
self.fdelay.fdelay_configure_pulse_gen(self.handle, c_int(channel), c_int(enable), t,
c_ulonglong(width), c_ulonglong(delta), c_int(count))
--
1.7.4.1
This diff is collapsed.
*.o
fd_test
\ No newline at end of file
#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
/*
Register definitions for slave core: Fine Delay Channel WB Slave
* File : fd_channel_regs.h
* Author : auto-generated by wbgen2 from fd_channel_wishbone_slave.wb
* Created : Wed Apr 11 11:05:22 2012
* Standard : ANSI C
THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE fd_channel_wishbone_slave.wb
DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
*/
#ifndef __WBGEN2_REGDEFS_FD_CHANNEL_WISHBONE_SLAVE_WB
#define __WBGEN2_REGDEFS_FD_CHANNEL_WISHBONE_SLAVE_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: Delay Control Register */
/* definitions for field: Enable channel in reg: Delay Control Register */
#define FD_DCR_ENABLE WBGEN2_GEN_MASK(0, 1)
/* definitions for field: Delay mode select in reg: Delay Control Register */
#define FD_DCR_MODE WBGEN2_GEN_MASK(1, 1)
/* definitions for field: Pulse generator arm in reg: Delay Control Register */
#define FD_DCR_PG_ARM WBGEN2_GEN_MASK(2, 1)
/* definitions for field: Pulse generator triggered in reg: Delay Control Register */
#define FD_DCR_PG_TRIG WBGEN2_GEN_MASK(3, 1)
/* definitions for field: Start Delay Update in reg: Delay Control Register */
#define FD_DCR_UPDATE WBGEN2_GEN_MASK(4, 1)
/* definitions for field: Delay Update Done in reg: Delay Control Register */
#define FD_DCR_UPD_DONE WBGEN2_GEN_MASK(5, 1)
/* definitions for field: Force Calibration Delay in reg: Delay Control Register */
#define FD_DCR_FORCE_DLY WBGEN2_GEN_MASK(6, 1)
/* definitions for field: Disable Fine Part update in reg: Delay Control Register */
#define FD_DCR_NO_FINE WBGEN2_GEN_MASK(7, 1)
/* definitions for register: Fine Range Register */
/* definitions for register: Pulse start time / offset (MSB TAI seconds) */
/* definitions for register: Pulse start time / offset (LSB TAI seconds) */
/* definitions for register: Pulse start time / offset (8 ns cycles) */
/* definitions for register: Pulse start time / offset (sub-cycle fine part) */
/* definitions for register: Pulse end time / offset (MSB TAI seconds) */
/* definitions for register: Pulse end time / offset (LSB TAI seconds) */
/* definitions for register: Pulse end time / offset (8 ns cycles) */
/* definitions for register: Pulse end time / offset (sub-cycle fine part) */
/* definitions for register: Pulse spacing (TAI seconds) */
/* definitions for register: Pulse spacing (8 ns cycles) */
/* definitions for register: Pulse spacing (sub-cycle fine part) */
/* definitions for register: Repeat Count Register */
/* definitions for field: Repeat Count in reg: Repeat Count Register */
#define FD_RCR_REP_CNT_MASK WBGEN2_GEN_MASK(0, 16)
#define FD_RCR_REP_CNT_SHIFT 0
#define FD_RCR_REP_CNT_W(value) WBGEN2_GEN_WRITE(value, 0, 16)
#define FD_RCR_REP_CNT_R(reg) WBGEN2_GEN_READ(reg, 0, 16)
/* definitions for field: Continuous Waveform Mode in reg: Repeat Count Register */
#define FD_RCR_CONT WBGEN2_GEN_MASK(16, 1)
/* [0x0]: REG Delay Control Register */
#define FD_REG_DCR 0x00000000
/* [0x4]: REG Fine Range Register */
#define FD_REG_FRR 0x00000004
/* [0x8]: REG Pulse start time / offset (MSB TAI seconds) */
#define FD_REG_U_STARTH 0x00000008
/* [0xc]: REG Pulse start time / offset (LSB TAI seconds) */
#define FD_REG_U_STARTL 0x0000000c
/* [0x10]: REG Pulse start time / offset (8 ns cycles) */
#define FD_REG_C_START 0x00000010
/* [0x14]: REG Pulse start time / offset (sub-cycle fine part) */
#define FD_REG_F_START 0x00000014
/* [0x18]: REG Pulse end time / offset (MSB TAI seconds) */
#define FD_REG_U_ENDH 0x00000018
/* [0x1c]: REG Pulse end time / offset (LSB TAI seconds) */
#define FD_REG_U_ENDL 0x0000001c
/* [0x20]: REG Pulse end time / offset (8 ns cycles) */
#define FD_REG_C_END 0x00000020
/* [0x24]: REG Pulse end time / offset (sub-cycle fine part) */
#define FD_REG_F_END 0x00000024
/* [0x28]: REG Pulse spacing (TAI seconds) */
#define FD_REG_U_DELTA 0x00000028
/* [0x2c]: REG Pulse spacing (8 ns cycles) */
#define FD_REG_C_DELTA 0x0000002c
/* [0x30]: REG Pulse spacing (sub-cycle fine part) */
#define FD_REG_F_DELTA 0x00000030
/* [0x34]: REG Repeat Count Register */
#define FD_REG_RCR 0x00000034
#endif
This diff is collapsed.
#ifndef __FD_LIB_H
#define __FD_LIB_H
#include <stdint.h>
/* Number of fractional bits in the timestamps/time definitions. Must be consistent with the HDL bitstream. */
#define FDELAY_FRAC_BITS 12
/* fdelay_get_timing_status() return values: */
#define FDELAY_FREE_RUNNING 0x10 /* attached WR core is offline */
#define FDELAY_WR_OFFLINE 0x8 /* attached WR core is offline */
#define FDELAY_WR_READY 0x1 /* attached WR core is synchronized, we can sync the fine delay core anytime */
#define FDELAY_WR_SYNCING 0x2 /* local oscillator is being synchronized with WR clock */
#define FDELAY_WR_SYNCED 0x4 /* we are synced. */
/* fdelay_configure_sync() flags */
#define FDELAY_SYNC_LOCAL 0x1 /* use local oscillator */
#define FDELAY_SYNC_WR 0x2 /* use White Rabbit */
/* Hardware "handle" structure */
typedef struct fdelay_device
{
/* Base address of the FD core */
uint32_t base_addr;
/* Bus-specific readl/writel functions - so the same library can be used both with
RawRabbit, VME and Etherbone backends */
void (*writel)(void *priv, uint32_t data, uint32_t addr);
uint32_t (*readl)(void *priv, uint32_t addr);
void *priv_fd; /* pointer to Fine Delay library private data */
void *priv_io; /* pointer to the I/O routines private data */
} fdelay_device_t;
typedef struct
{
int64_t utc;
int32_t coarse;
int32_t frac;
uint16_t seq_id;
int channel;
} fdelay_time_t;
/*
--------------------
PUBLIC API
--------------------
*/
fdelay_device_t *fdelay_create_rawrabbit(int fd, uint32_t base_addr);
fdelay_device_t *fdelay_create_minibone(char *iface, char *mac_addr, uint32_t base_addr);
fdelay_time_t fdelay_from_picos(const uint64_t ps);
int64_t fdelay_to_picos(const fdelay_time_t t);
int fdelay_init(fdelay_device_t *dev);
int fdelay_release(fdelay_device_t *dev);
int fdelay_read(fdelay_device_t *dev, fdelay_time_t *timestamps, int how_many);
int fdelay_configure_trigger(fdelay_device_t *dev, int enable, int termination);
int fdelay_configure_output(fdelay_device_t *dev, int channel, int enable, int64_t delay_ps, int64_t width_ps, int64_t delta_ps, int rep_count);
int fdelay_configure_sync(fdelay_device_t *dev, int mode);
int fdelay_update_sync_status(fdelay_device_t *dev);
int fdelay_set_time(fdelay_device_t *dev, const fdelay_time_t t);
int fdelay_configure_pulse_gen(fdelay_device_t *dev, int channel, int enable, fdelay_time_t t_start, int64_t width_ps, int64_t delta_ps, int rep_count);
int fdelay_channel_triggered(fdelay_device_t *dev, int channel);
int fdelay_get_time(fdelay_device_t *dev, fdelay_time_t *t);
#endif
/*
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 */
/* 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
/* ACAM Calibration parameters */
struct fine_delay_calibration {
uint32_t magic; /* magic ID: 0xf19ede1a */
uint32_t zero_offset[4]; /* Output zero offset, in nsec << FDELAY_FRAC_BITS */
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 picoseconds */
int64_t frr_poly[3]; /* SY89295 delay/temperature polynomial coefficients */
} __attribute__((packed));
/* 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;
struct fine_delay_calibration 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