Commit 95332c0c authored by Federico Vaga's avatar Federico Vaga

doc: move from texinfo to sphinx

Signed-off-by: Federico Vaga's avatarFederico Vaga <federico.vaga@cern.ch>
parent 4bfacace
# Minimal makefile for Sphinx documentation
#
# Makefile for the documentation directory
#
# Copyright 1994,2000,2010,2011 Alessandro Rubini <rubini@linux.it>
#
#################
# There is not basenames here, all *.in are considered input
INPUT = $(wildcard *.in)
TEXI = $(INPUT:.in=.texi)
INFO = $(INPUT:.in=.info)
HTML = $(INPUT:.in=.html)
TXT = $(INPUT:.in=.txt)
PDF = $(INPUT:.in=.pdf)
ALL = $(INFO) $(HTML) $(TXT) $(PDF)
MAKEINFO ?= makeinfo
RELEASE=$(shell git describe --always --dirty)
%.texi: %.in
@rm -f $@
sed s/__RELEASE_GIT_ID__/$(RELEASE)/ $< | sed -f ./infofilter > $@
emacs -batch --no-site-file -l fixinfo $@
chmod -w $@
%.pdf: %.texi
texi2pdf --batch $<
%.info: %.texi
$(MAKEINFO) $< -o $@
%.html: %.texi
$(MAKEINFO) --html --no-split -o $@ $<
%.txt: %.texi
$(MAKEINFO) --no-headers $< > $@
##############################################
.PHONY: all images check terse clean install
.INTERMEDIATE: $(TEXI)
all: images $(ALL)
$(MAKE) terse
images::
if [ -d images ]; then $(MAKE) -C images || exit 1; fi
check: _err.ps
gs -sDEVICE=linux -r320x200x16 $<
terse:
for n in cp fn ky pg toc tp vr aux log; do rm -f *.$$n; done
rm -f *~
# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = .
BUILDDIR = _build
clean: terse
rm -f $(ALL) $(TEXI)
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
install:
.PHONY: help Makefile
# add the other unused targets, so the rule in ../Makefile works
modules modules_install:
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
# Configuration file for the Sphinx documentation builder.
#
# This file only contains a selection of the most common options. For a full
# list see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
# -- Path setup --------------------------------------------------------------
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
# import os
# import sys
# sys.path.insert(0, os.path.abspath('.'))
# -- Project information -----------------------------------------------------
project = 'Fmc Fine-Delay Software'
copyright = '2020, Alessandro Rubini'
author = 'Alessandro Rubini'
# -- General configuration ---------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The master toctree document.
master_doc = 'index'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = 'alabaster'
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
This diff is collapsed.
======
Driver
======
Driver Features
===============
This driver is based on *zio* and *fmc-bus*. It supports initial
setup of the board, setting and reading time, run-time continuous
calibration, input timestamping, output pulse generation and readback of
output settings from the hardware. It supports user-defined offsets,
so our users can tell the driver about channel-specific delays (for
example, to account for wiring) and ignore the issue in application code.
For each feature offered the driver (and documentation) the driver
tries to offer
the following items; sometimes however one of them is missing for a specific
driver functionality, if we don't consider it important enough.
* A description of how the features works at low level;
* A low-level user-space program to test the actual mechanism;
* A C-language API to access the feature with data structures;
* An example program based on that API.
.. _drv_param:
Module Parameters
=================
The driver accepts a few load-time parameters for configuration. You
can pass them to *insmod* amd *modprobe* directly, or write them
in ``/etc/modules.conf`` or the proper file in ``/etc/modutils/``.
The following parameters are used:
verbose=
The parameter defaults to 0. If set, it enables more diagnostic
messages during probe (you may find it is not used, but it is
left in to be useful during further development, and avoid
compile-time changes like use of ``DEBUG``).
timer_ms=
The period of the internal timer, if not zero.
The timer is used to poll for input events instead of enabling
the interrupt. The default interval is 0, which means to
use interrupt support. You may want to use the timer while
porting to a different carrier, before sorting out IRQ issues.
calib_s=
The period, in seconds, of temperature measurement to re-calibrate
the output delays. Defaults to 30. If set to zero, the
re-calibration timer is not activated.
The module also uses the two parameters provided by the *fmc*
framework:
busid=
A list of bus identifiers the driver will accept to driver.
Other identifiers will lead to a failure in the *probe*
function. The meaning of the identifiers is carrier-specific;
the SPEC uses the bus number and *devfn*, where the latter
is most likely zero.
gateware=
A list of gateware file names. The names passed are made to
match the *busid* parameters, in the same order. This
means that you can't make the driver load a different gateware
file without passing the respective *busid*. Actually, to
change the gateware for all boards, you may just replace
the file in ``/lib/firmware``. (Maybe I'll add an
option to change the name at load time for all boards).
For example, this host has two SPEC cards:::
spusa.root# lspci | grep CERN
02:00.0 Non-VGA unclassified device: CERN/ECP/EDU Device 018d (rev 03)
04:00.0 Non-VGA unclassified device: CERN/ECP/EDU Device 018d (rev 03)
One of the cards hosts a *fine-delay* mezzanine and the other does
not. FMC identifiers are not yet used by this driver at this point in time.
(They will be there in the next release: code is there but not finalized).
So, here you can use ``busid=`` to choose which SPEC must use *fine-delay*,
leaving the other one alone:::
spusa.root# insmod fmc-fine-delay.ko busid=0x0200
[ 4603.994936] spec 0000:02:00.0: Driver has no ID: matches all
[ 4604.000624] spec 0000:02:00.0: reprogramming with fmc/fine-delay.bin
[ 4604.206515] spec 0000:02:00.0: FPGA programming successful
[ 4604.212442] spec 0000:02:00.0: Gateware successfully loaded
[ 4604.218037] spec 0000:02:00.0: fd_regs_base is 80000
[ 4604.223023] spec 0000:02:00.0: fmc_fine_delay: initializing
[ 4604.228624] spec 0000:02:00.0: calibration: version 3, date 20130427
[ 4605.691404] fd_read_temp: Scratchpad: 9f:04:4b:46:7f:ff:01:10:89
[ 4605.697615] fd_read_temp: Temperature 0x49f (12 bits: 73.937)
[ 4606.645545] fd_calibrate_outputs: ch1: 8ns @@859 (f 827, off 32, t 71.00)
[ 4606.815228] fd_calibrate_outputs: ch2: 8ns @@867 (f 827, off 40, t 71.00)
[ 4607.001027] fd_calibrate_outputs: ch3: 8ns @@854 (f 827, off 27, t 71.00)
[ 4607.187007] fd_calibrate_outputs: ch4: 8ns @@859 (f 827, off 32, t 71.00)
[ 4607.356103] fmc_fine_delay: Found i2c device at 0x50
[ 4607.364039] spec 0000:02:00.0: Using interrupts for input
[ 4607.369549] spec 0000:04:00.0: Driver has no ID: matches all
[ 4607.375243] spec 0000:04:00.0: not using "fmc_fine_delay" according to modparam
If you use ``show_sdb=1``, you'll get the following dump of the
internal SDB structure to ``printk``. The *Self Describing Bus* data
structure is described in the documentation of the
*fpga-config-space* project, under http://ohwr.org.::
SDB: 00000651:e6a542c9 WB4-Crossbar-GSI
SDB: 0000ce42:f19ede1a Fine-Delay-Core (00010000-000107ff)
SDB: 0000ce42:f19ede1a Fine-Delay-Core (00020000-000207ff)
SDB: 0000ce42:00000013 WB-VIC-Int.Control (00030000-000300ff)
SDB: 00000651:eef0b198 WB4-Bridge-GSI (bridge: 00040000)
SDB: 00000651:e6a542c9 WB4-Crossbar-GSI
SDB: 0000ce42:66cfeb52 WB4-BlockRAM (00040000-00055fff)
SDB: 00000651:eef0b198 WB4-Bridge-GSI (bridge: 00060000)
SDB: 00000651:e6a542c9 WB4-Crossbar-GSI
SDB: 0000ce42:ab28633a WR-Mini-NIC (00060000-000600ff)
SDB: 0000ce42:650c2d4f WR-Endpoint (00060100-000601ff)
SDB: 0000ce42:65158dc0 WR-Soft-PLL (00060200-000602ff)
SDB: 0000ce42:de0d8ced WR-PPS-Generator (00060300-000603ff)
SDB: 0000ce42:ff07fc47 WR-Periph-Syscon (00060400-000604ff)
SDB: 0000ce42:e2d13d04 WR-Periph-UART (00060500-000605ff)
SDB: 0000ce42:779c5443 WR-Periph-1Wire (00060600-000606ff)
SDB: 0000ce42:779c5445 WR-Periph-AuxWB (00060700-000607ff)
SDB: Bitstream 'svec-fine-delay' synthesized 20140317 by twlostow \
(ISE version 133), commit e95b10c776f5f7603f49fcf1330e0c07
SDB: Synthesis repository: git://ohwr.org/fmc-projects/fmc-delay-1ns-8cha.git
The module also supports some more parameters that are
calibration-specific. They are described in the :ref:`Calibration<dev_cal>`
section.
This diff is collapsed.
;; use:
;; emacs -batch -l ./fixinfo.el <file>
;; or, better:
;; emacs -batch --no-site-file -l ./fixinfo.el <file>
(defun fixinfo (file)
(find-file-other-window file)
(message (concat "Maxing texinfo tree in " file))
(texinfo-all-menus-update)
(texinfo-every-node-update)
(save-buffer)
(kill-buffer (current-buffer))
)
;; loop over command line arguments
(mapcar 'fixinfo command-line-args-left)
(kill-emacs)
Welcome to Fmc Fine-Delay Software's documentation!
===================================================
.. toctree::
:maxdepth: 2
:caption: Contents:
introduction
installation
driver
library
tools
developer-info
troubleshooting
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
============
Installation
============
This driver depends on four other modules (four http://ohwr.org.}
packages), as well as the Linux kernel. Also, it
must talk to a specific FPGA binary file running in the device.
Gateware Dependencies
=====================
While previous versions of this package included a gateware binary
in the ``binaries/`` subdirectory, in Jan 2014 we decided not to do
that any more. Release versions of this package are expected to
point to ``current`` gateware images for different carriers.
Clearly the driver is expected to work on any *fmc* carrier,
even those ignored to us, and we can't provide all binaries.
The up-to-date gateware binaries for the SVEC and SPEC carriers will be
always available in the *Releases* section of the Fine Delay project:
http://www.ohwr.org/projects/fmc-delay-1ns-8cha/wiki/Releases
Note that the release gateware contains a stable version of
the White Rabbit PTP Core firmware. This firmware may be reloaded dynamically
at any time using carrier-specific tools.
Gateware Installation
=====================
By default, the driver looks for a gateware file named
``/lib/firmware/fmc/[carrier]-fine-delay.bin``, where ``[carrier]`` is the
carrier's name (lowercase - currently ``svec`` or ``spec``). There are two ways
to install the gateware:
* The easy way: run ``make gateware_install`` in the target system. This will
automatically download all required files and install them in the right
place.
* The difficult way: download the bitstreams from the Release page (or build
your own, as you wish) and put them in ``/lib/firmware/fmc``. You may have
to strip the version/date attached to the file names or create symlinks.
If you have several *fine-delay* cards in the same host, you can
load different binaries for different cards, using appropriate
module parameters. Loading custom gateware files
is advised only for advanced users/developers.
Software Dependencies
=====================
The kernel versions I am using during development is 3.4. Everything
used here is known to build with all versions from 2.6.35 to 3.12.
The driver, then, is based on the *zio* framework, available from
http://ohwr.org.. This version of *zio* doesn't build with 3.13, for
a minor incompatibility, so this version of *fine-delay-sw* is
limited to Linux 3.12 as well.
The FMC mezzanine is supported by means of the *fmc-bus*
software project. This *fine-delay* kernel module registers as
a *driver* for the FMC bus abstraction, and is verified with
version ``v2014-02`` of the FMC package. The same kernel range applies.
Both packages (*zio* and *fmc-bus*) are currently checked out as
*git submodules* of this package, and each of them is retrieved at
the right version to be compatible with this driver. This means you may just
ignore software dependencies and everything should work.
*fmc* support is a *bus* in the Linux way, so you need both
a *device* and a *driver*. This driver is known to work both
with the *spec* carrier on *pci* and the *svec* carrier
on *vme*. The software packages that provide the respective *device*
are called *spec-sw* and *svec-sw*; both are hosted on http://ohwr.org.
Most of the non-*cern* users are expected to run the *spec*
carrier, so a compatible version of *spec-sw* is downloaded
as a submodule, too.
Software Installation
=====================
To install this software package, you need to tell it where your
kernel sources live, so the package can pick the right header files.
You need to set only one environment variable:
LINUX
The top-level directory of the Linux kernel you are compiling
against. If not set, the default may work if you compile in the same
host where you expect to run the driver.
Most likely, this is all you need to set. After this, you can
run:::
make
sudo make install gateware_install LINUX=$LINUX
In addition to the normal installation procedure for
``fmc-fine-delay.ko`` you'll see the following message:::
WARNING: Consider "make prereq_install"
The *prerequisite* packages are *zio* and *fmc-bus*;
unless you already installed your own preferred version, you are
expected to install the version this packages suggests. This step
can be performed by:::
make
sudo make prereq_install LINUX=$LINUX
The step is not performed by default to avoid overwriting some
other versions of the drivers. After ``make prereq_install``,
the warning message won't be repeated any more if you change this
driver and ``make install`` again.
After installation, your carrier driver should load automatically
(for example, the PCI bus will load ``spec.ko``), but ``fmc-fine-delay.ko``
must be loaded manually, because support for automatic loading is not
yet in place. The suggested command is one or the other of the following two:::
modprobe fmc-fine-delay [<parameter> ...] # after make install
insmod kernel/fmc-fine-delay.ko [<parameter> ...] # if not installed
Available module parameters are described in :ref:`Module Parameters<drv_param>`.
Unless you customized or want to customize one of the three
related packages, you can skip the rest of this section.
In order to compile *fine-delay* against a specific repository of one
of the related packages, ignoring the local *submodule*
you can use one or more of the following environment variables:
* ZIO, FMC_BUS, SPEC_SW
The top-level directory of the repository checkout of each
package. Most users won't need to set them, as the Makefiles
point them to the proper place by default.
If any of the above is set, headers and dependencies for the
respective package are taken from the chosen directory. If you
``make prereq_install`` with any of these variables set, they are
be used to know where to install from, instead of using local submodules.
============
Introduction
============
This is the user manual for the *fmc-delay-1ns-4cha* board developed on
http://ohwr.org. Please note that the ohwr hardware project is
misnamed as *fmc-delay-1ns-8cha*; even if the board has 4
channels; the references to *8ch* below are thus correct, even if
the may seem wrong.
Repositories and Releases
=========================
The code and documentation is distributed in the following places:
http://www.ohwr.org/projects/fine-delay-sw/documents
This place hosts the pdf documentation for some official
release, but we prefer to use the *files* tab, below.
http://www.ohwr.org/projects/fine-delay-sw/files
Here we place the *.tar.gz* file for every release,
including the *git* tree and compiled documentation (for
those who lack TeX), as well as manuals.
git://ohwr.org/fmc-projects/fmc-delay-1ns-8cha/fine-delay-sw.git
Read-only repositories for the software and documentation.
git@@ohwr.org:fmc-projects/fmc-delay-1ns-8cha/fine-delay-sw.git
Read-write repositories, for those authorized.
.. note::
If you got this from the repository (as opposed to a named
*tar.gz* or *pdf* file) it may happen that you are looking at a later
commit than the release this manual claims to document.
It is a fact of life that developers forget
to re-read and fix documentation while updating the code. In that case,
please run ``git describe HEAD`` to ensure where you are.
Hardware Description
====================
The *FMC Delay 1ns-4cha* is an FPGA Mezzanine Card (FMC - VITA 57 standard),
whose main purpose is to produce pulses delayed by a user-programmed value with
respect to the input trigger pulse. The card can also work as a Time to
Digital converter (TDC) or as a programmable pulse generator triggering at a
given TAI time.
For the sake of clarity of this document, the card's name will be further
abbreviated as *fine-delay*.
Requirements and Supported Platforms
====================================
*fine-delay* can work with any VITA 57-compliant FMC carrier, provided that
the carrier's FPGA has enough logic resources. The current software/gateware
release officially supports the following carrier and mezzanine combinations:
* CERN's SPEC (Simple PCI-Express Carrier) with one *fine-delay* mezzanine.
* CERN's SVEC (Simple VME64x Carrier) with one or two *fine-delay* mezzanines.
Note that if only one *fine-delay* is in use, the other slot should be left
empty.
Aside from the FMC and its carrier, the following hardware/software components
are required:
* For the PCI version: a standard PC with at least one free 4x (or wider)
PCI-Express slot.
* For the VME version: a VME64x crate with a MEN A20 CPU.
* 50-ohm cables with 1-pin LEMO 00 plugs for connecting the I/O signals.
* Any Linux (kernel 2.6 or 3.0+) distribution. Backports are provided down to
kernel ``2.6.24``.
Modes of Operation
==================
*fine-delay* can work in one or more of the following modes:
* **Pulse Delay**: produces one or more pulse(s) on selected outputs
a given time after an input trigger pulse (fig. 1a).
* **Pulse Generator**: produces one or more pulse(s) on selected outputs
starting at an absolute time value programmed by the user (fig. 1b).
In this mode, time base is usually provided by the White Rabbit network.
* **Time to Digital Converter**: tags all trigger pulses and delivers the
timestamps to the user's application.
.. image:: drawings/func.eps
:alt: *fine-delay* operating modes.
Modes (pulse delay/generator) can be selected independently for each output.
For example, one can configure the output 1 to delay trigger pulses
by 1 us, and the output 2 to produce a pulse at the beginning of each second.
The TDC mode can be enabled for the input at any time and
does not interfere with the operation of the channels being time tagged.
Mechanical/Environmental
========================
.. image:: drawings/front_panels.eps
:alt: *fine-delay* front panel connector layout.
**Mechanical and environmental specs:**
* Format: FMC (VITA 57), with rear zone for conduction cooling.
* Operating temperature range: 0 - 90 degC.
* Carrier connection: 160-pin Low Pin Count FMC connector.
Electrical
==========
**Inputs/Outputs:**
* 1 trigger input (LEMO 00).
* 4 pulse outputs (LEMO 00).
* 2 LEDs (termination status and trigger indicator).
* Carrier communication via 160-pin Low Pin Count FMC connector.
**Trigger input:**
* TTL/LVTTL levels, DC-coupled. Reception of a trigger pulse is indicated by
blinking the "TRIG" LED in the front panel.
* 2 kOhm or 50 Ohm input impedance (programmable via software).
50 Ohm termination is indicated by the "TERM" LED in the front panel.
* Power-up input impedance: 2 kOhm.
* Protected against short circuit, overcurrent (> 200 mA) and overvoltage
(up to +28 V).
* Maximum input pulse edge rise time: 20 ns.
**Outputs:**
* TTL-compatible levels DC-coupled: Voh = 3 V, Vol = 200 mV (50 Ohm load),
Voh = 6 V, Vol = 400 mV (high impedance).
* Output impedance: 50 Ohm (source-terminated).
* Rise/fall time: 2.5 ns (10%% - 90%%, 50 Ohm load).
* Power-up state: LOW (2 kOhm pulldown), guaranteed glitch-free.
* Protected against continuous short circuit, overcurrent and overvoltage
(up to +28 V).
**Power supply:**
* Used power supplies: P12V0, P3V3, P3V3_AUX, VADJ (voltage monitor only).
* Typical current consumption: 200 mA (P12V0) + 1.5 A (P3V3).
* Power dissipation: 7 W. Forced cooling is required.
Timing
======
.. image:: drawings/io_timing.eps
:alt: *fine-delay* timing parameter definitions.
**Time base:**
* On-board oscillator accuracy: +/- 2.5 ppm (i.e. max. 2.5 ns error for a
delay of 1 ms).
* When using White Rabbit as the timing reference: depending on the
characteristics of the grandmaster clock and the carrier used. On SPEC
v 4.0 FMC carrier, the accuracy is better than 1 ns.
**Input timing:**
* Minimum pulse width: :math:`t_{IW}` = 50 ns. Pulses below 24 ns are rejected.
* Minimum gap between the last delayed output pulse and subsequent trigger
pulse: :math:`T_{LT}` = 50 ns.
* Input TDC performance: 400 ps pp accuracy, 27 ps resolution,
70 ps trigger-to-trigger rms jitter (measured at 500 kHz pulse rate).
**Output timing:**
* Resolution: 10 ps.
* Accuracy (pulse generator mode): 300 ps.
* Train generation: trains of 1-65536 pulses or continuous square wave up
to 10 MHz.
* Output-to-output jitter (outputs programmed to the same delay): 10 ps rms.
* Output-to-output jitter (outputs programmed to to different delays, worst
case): 30 ps rms.
* Output pulse spacing (:math:`T_{SP}`) : 100 ns - 16 s. Adjustable in 10 ps
steps when both :math:`T_{PW}`, :math:`T_{GAP}` > 200 ns. Outside that range,
:math:`T_{SP}` resolution is limited to 4 ns.
* Output pulse start (:math:`t_{START}`) resolution: 10 ps for the rising edge
of the pulse, 10 ps for subsequent pulses if the condition above is met,
otherwise 4 ns.
**Delay mode specific parameters:**
* Delay accuracy: < 1 ns.
* Trigger-to-output jitter: 80 ps rms.
* Trigger-to-output delay: minimum :math:`T_{DLY}` = 600 ns,
maximum :math:`T_{DLY}` = 120 s.
* Maximum trigger pulse rate: :math:`T_{DLY} + N*(T_{SP} + T_{GAP}) +` 100 ns,
where N = number of output pulses.
* Trigger pulses are ignored until the output with the biggest delay has
finished generation of the pulse(s).
Principles of Operation
=======================
.. note::
if you are an electronics engineer, you can skip this section, as
you will most likely find it rather boring.
.. image:: drawings/analog_digital_delays.eps
:alt: Principle of operation of analog and digital delay generators.
Contrary to typical analog delay cards, which work by comparing an analog ramp
triggered by the input pulse with a voltage proportional to the desired delay,
*fine-delay* is a digital delay generator, which relies on time tag arithmetic.
The principle of operation of both generators is illustrated in figure 3.
When a trigger pulse comes to the input, *fine-delay* first produces its'
precise time tag using a Time-to-Digital converter (TDC). Afterwards,
the time tag is summed together with the delay preset and the result is
passed to a digital pulse generator.
In its simplest form, it consists of a free running counter and a comparator.
When the counter reaches the value provided on the input, a pulse is produced
on the output.
Note that in order for the system to work correctly, both the TDC and
the Pulse Generator must use exactly the same time base (not shown on
the drawings).
Digital architecture brings several advantages compared to analog
predecessors: Timestamps generated by the TDC can be also passed to
the host system, and the Pulse Generators can be programmed with arbitrary
pulse start times instead of :math:`t_{TRIG} + T_{DLY}`. Therefore,
*fine-delay* can be used simultaneously as a TDC, pulse generator or
a pulse delay.
======================
Using the Provided API
======================
This chapter describes the higher level interface to the board,
designed for user applications to use. The code lives in the *lib}
subdirectory of this package. The directory uses a plain Makefile (not
a Kbuild one) so it can be copied elsewhere and compiled stand-alone.
Only, it needs a copy of ``fine-delay.h`` (which it currently pulls
from the parent directory) and the *zio* headers, retrieved using the
``ZIO`` environment variable).
.. _lib_init:
Initialization and Cleanup
==========================
The library offers the following structures and functions:
``struct fdelay_board``
This is the ``opaque`` token that is being used by library clients.
If you want to see the internals define ``FDELAY_INTERNAL``
and look at *fdelay_list.c*.
``int fdelay_init(void)``, `` void fdelay_exit(void)``
The former function allocates its internal data and returns
the number of boards currently found on the system. The latter
releases any allocated data. If *init* fails, it returns -1 with
a proper ``errno`` value. If no boards are there it returns 0.
You should not load or unload drivers between *init* and *exit*.
``struct fdelay_board *fdelay_open(int index, int dev_id)``, ``int fdelay_close(struct fdelay_board *)``
The former function opens a board and returns a token that can
be used in subsequent calls. The latter function undoes it.
You can refer to a board either by index or by
``dev_id``. Either argument (but not both) may be -1. If both
are different from -1 the index and dev_id must match. If a mismatch
is found, the function return NULL with ``EINVAL``; if either index or
``dev_id`` are not found, the function returns NULL with ``ENODEV``.
``struct fdelay_board *fdelay_open_by_lun(int lun)``
The function opens a pointer to a board, similarly to *fdelay_open*,
but it uses the Logical Unit Number as argument instead. The LUN
is used internally be CERN libraries, and the function is needed
for compatibility with the installed tool-set. The function uses
a symbolic link in *dev*, created by the local installation procedure.
Example code: all tools in ``tools/`` subdirectory.
.. _lib_time:
Time Management
===============
These are the primitives the library offers for time management, including
support for White Rabbit network synchronization.
``struct fdelay_time``
The structure has the same fields as the one in the initial
user-space library. All but *utc* are unsigned 32-bit values
whereas they were different types in the first library.
``int fdelay_set_time(struct fdelay_board *b, struct fdelay_time *t)``, ``int fdelay_get_time(struct fdelay_board *b, struct fdelay_time *t)``
The functions are used to set board time from a user-provided
time, and to retrieve the current board time to user space.
The functions return 0 on success. They only use the fields
*utc* and *coarse* of ``struct fdelay_time``.
``int fdelay_set_host_time(struct fdelay_board *b)``
The function sets board time equal to host time. The precision
should be in the order of 1 microsecond, but will drift over time. This function is only provided to
coarsely correlate the board time with the system time. Relying on system time
for synchronizing multiple *fine-delays* is strongly discouraged.
``int fdelay_wr_mode(struct fdelay_board *b, int on)``
The function enables/disables White Rabbit mode.
It may fail with ``ENOTSUPP`` if there's no White Rabbit support in the
gateware.
``int fdelay_check_wr_mode(struct fdelay_board *b)``
The function returns 0 if the WR slave is synchronized, ``EAGAIN``
if it is enabled by not yet synchronized, ``ENODEV``
if WR-mode is currently disabled and ``ENOLINK`` if the WR link is down (e.g. unconnected cable).
Example code: ``fmc-fdelay-board-time`` tool.
.. _lib_input:
Input Configuration
===================
To configure the input channel for a board, the library offers the
following function and macros:
``int fdelay_set_config_tdc(struct fdelay_board *b, int flags)``, ``int fdelay_get_config_tdc(struct fdelay_board *b)``
The function configures a few options in the input channel.
The *flags* argument is a bit-mask of the following three
values (note that 0 is the default at initialization time).
The function returns -1 with ``EINVAL`` if the *flags*
argument includes undefined bits.
``FD_TDCF_DISABLE_INPUT``, ``FD_TDCF_DISABLE_TSTAMP``, ``FD_TDCF_TERM_50``
The first bit disables the input channel, the second disables
acquisition of timestamps, and the last enables the 50-ohm
termination on the input channel.
Example code: ``fmc-fdelay-term`` tool.
Reading Input Timestamps
========================
The library offers the following functions that deal with the input stamps:
``int fdelay_fread(struct fdelay_board *b, struct fdelay_time *t, int n)``
The function behaves like *fread*: it tries to read all samples,
even if it implies sleeping several times. Use it only if you are
aware that all the expected pulses will reach you.
``int fdelay_read(struct fdelay_board *b, struct fdelay_time *t, int n, int flags)``
The function behaves like *read*: it will wait at most once
and return the number of samples that it received. The *flags*
argument is used to pass 0 or ``O_NONBLOCK``. If a non-blocking
read is performed, the function may return -1 with ``EAGAIN``
if nothing is pending in the hardware FIFO.
``int fdelay_fileno_tdc(struct fdelay_board *b)``
This returns the file descriptor associated to the TDC device,
so you can *select* or *poll* before calling *fdelay_read*.
If access fails (e.g., for permission problems), the functions
returns -1 with ``errno`` properly set.
.. _lib_output:
Output Configuration
====================
The library offers the following functions for output configuration:
``int fdelay_config_pulse(board, channel, pulse_cfg)``, ``int fdelay_config_pulse_ps(board, channel, pulse_ps_cfg)``
The two functions configure the channel
for pulse or delay mode. The channel numbers are 0..3 (that is, the number of the output on the
front panel minus 1, you may use ``FDELAY_OUTPUT`` macro to convert). The former function receives
``struct fdelay_pulse`` (with split utc/coarse/frac times)
while the latter receives ``struct fdelay_pulse_ps``, with
picosecond-based time values. The functions return 0 on success, -1
and an error code in ``errno`` in case of failure.
``int fdelay_get_config_pulse(board, channel, pulse_cfg)``, ``int fdelay_get_config_pulse_ps(board, channel, pulse_ps_cfg)``
The two functions return the configuration of the channel
(numbered 0..3) read from the hardware. They may be used to check
the correctness of outputs' programming. The former function returns
``struct fdelay_pulse`` (with split utc/coarse/frac times)
while the latter returns ``struct fdelay_pulse_ps``, with
picosecond-based time values.
``int fdelay_has_triggered(struct fdelay_board *b, int channel)``
The function returns 1 of the output channel (numbered 0..3) has
triggered since the last configuration request, 0 otherwise.
The configuration functions receive a time configuration. The
starting time is passed as ``struct fdelay_time``, while the
pulse end and loop period are passed using either the same structure
or a scalar number of picoseconds. These are the relevant structures:::
struct fdelay_time {
uint64_t utc;
uint32_t coarse; uint32_t frac;
uint32_t seq_id; uint32_t channel;
};
struct fdelay_pulse {
int mode; int rep; /* -1 == infinite */
struct fdelay_time start, end, loop;
};
struct fdelay_pulse_ps {
int mode; int rep;
struct fdelay_time start;
uint64_t length, period;
};
The ``rep`` field represents the repetition count, to output a
train of pulses. The mode field is one of ``FD_OUT_MODE_DISABLED``,
``FD_OUT_MODE_DELAY``, ``FD_OUT_MODE_PULSE``.
Example code: ``fmc-fdelay-pulse`` tool.
Miscellanous functions
======================
``void fdelay_pico_to_time(uint64_t *pico, struct fdelay_time *time)``
Splits a time value expressed in picoseconds to *fine-delay*'s internal
time format (utc/coarse/frac).
``void fdelay_time_to_pico(struct fdelay_time *time, uint64_t *pico)``
Converts from *fine-delay*'s internal time format (utc/coarse/frac)
to plain picoseconds.
``float fdelay_read_temperature(struct fdelay_board *b)``
Returns the temperature of the given board, in degrees Celsius.
==================
Command Line Tools
==================
This chapter describes the command line tools that come with the
driver and reside in the ``tools/`` subdirectory. They are provided
as diagnostic utilities and to demonstrate how to use the library.
General Command Line Conventions
================================
Most tools accept the following command-line options, in a
consistent way:
``-d <devid>``, ``-i <index>``
Used to select one board among several. See the description
of *fdelay_open* in :ref:`Initialization and Cleanup<lib_init>`.
If no argument is given, the ``first`` board is used (index is 0).
fmc-fdelay-list
===============
The command takes no arguments. It reports the list of available
boards in the current system:::
spusa# ./tools/fmc-fdelay-list
./tools/fmc-fdelay-list: found 1 board
dev_id 0200, /dev/zio/zio-fd-0200, /sys/bus/zio/devices/zio-fd-0200
fmc-fdelay-term
===============
The command can be used to activate or deactivate the 50 ohm
termination resistor.
In addition to the ``-i`` or ``-d``
arguments, mandatory if more than one board is found on the
host system, the command receives one optional argument, either
``1`` or ``on`` (activate termination) or ``0`` or ``off``
(deactivate termination).
::
spusa# ./tools/fmc-fdelay-term on
./tools/fmc-fdelay-term: termination is on
If no arguments are passed the termination status is reported back but
not changed.
fmc-fdelay-board-time
=====================
The command is used to act on the time notion of the *fine-delay* card.
In addition to the ``-i`` or ``-d``
arguments, mandatory if more than one board is found on the
host system, the command receives one mandatory argument, that is
either a command or a floating point number. The number is the
time, in seconds, to be set in the card; the command is one of
the following ones:
get
Read board time and print to *stdout*.
host
Set board time from host time
wr
Lock the boards to White Rabbit time. It may block if no White
Rabbit is there. No timeout is currently available.
local
Detach the board from White Rabbit, and run local time instead.
Examples:::
spusa# ./lib/fdelay-board-time 25.5; ./lib/fdelay-board-time get
25.504007360
spusa# ./lib/fdelay-board-time get
34.111048968
spusa# ./lib/fdelay-board-time host
spusa# ./lib/fdelay-board-time get
1335974946.493415600
fmc-fdelay-input
================
The tool reports input pulses to stdout. It receives the
usual ``-i`` or ``-d`` arguments to select one board, mandatory
if more than one *fine-delay* card is found.
It receives the following options:
-c <count>
Number of pulses to print. Default (0) means run forever.
-n
Nonblocking mode: just print what is pending in the buffer.
-f
Floating point: print as a floatingpoint seconds.pico value.
The default is a human-readable string, where the decimal part
is split.
-r
Raw output: print the three hardware timestamps, in decimal.
This an example output, reading a pps signal through a 16ns cable:
::
spusa.root# ./tools/fmc-fdelay-input -c 3
seq 10921: time 11984:000,000,015,328 ps
seq 10922: time 11985:000,000,015,410 ps
seq 10923: time 11986:000,000,015,248 ps
spusa.root# ./tools/fmc-fdelay-input -c 3 -r
seq 10924: raw utc 11987, coarse 1, frac 3773
seq 10925: raw utc 11988, coarse 1, frac 3814
seq 10926: raw utc 11989, coarse 1, frac 3794
spusa.root# ./tools/fmc-fdelay-input -c 3 -f
seq 10927: time 11990.000000015328
seq 10928: time 11991.000000015410
seq 10929: time 11992.000000015410
In a future release we'll support reading concurrently from several
boards.
fmc-fdelay-pulse
================
The program can be used to program one of the output channels to
output a sequence of pulses. It can parse the following command-line
options:
``-o <output>``
Output channels are numbered 1 to 4, as written on the device panel.
Each command invocation can set only one output channel; the
last ``-o`` specified takes precedence.
``-c <count>``
Output repeat count: 0 is the default and means forever
``-m <mode>``
Output mode. Can be ``pulse``, ``delay`` or ``disable``.
``-r <reltime>``
Output pulse at a relative time in the future. The time is
a fraction of a second, specified as for ``-T`` and ``-w``,
described below. For delay mode the time is used as
a delay value from input events; for pulse mode the time
represents a fraction of the next absolute second.
``-D <date>``
Output pulse at a specified date. The argument is parsed
as ``<seconds>:<nanoseconds>``.
``-T <period>``, ``-w <width>``
Period and width of the output signal. A trailing ``m``,
``u``, ``n``, ``p`` means milli, micro, nano, pico, resp.
The parser supports additions and subtractions, e.g.
``50m-20n``.
The period defaults to 100ms and the width defaults to 8us
``-t``
Wait for the trigger to happen before returning. The boards reports
a trigger event when the requested pulse sequence is initiated,
either because the absolute time arrived or because an input
pulse was detected and the requested delay elapsed.
``-p``, ``-1``
Pulse-per-seconds and 10MHz. These are shorthands setting many
parameters.
``-v``
Verbose: report action to stdout before telling the driver.
This is, for example, how verbose operation reports the request for a single
pulse 300ns wide, 2 microseconds into the next second.:::
spusa.root# ./tools/fmc-fdelay-board-time get; \
./tools/fmc-fdelay-pulse -i 0 -o 1 -m pulse -r 2u -w 300n -c 1 -t -v
WR Status: disabled.
Time: 13728.801090400
Channel 1, mode pulse, repeat 1
start time 13729:000,002,000,000 ps
end time 13729:000,002,300,000 ps
loop time 0:100,000,000,000 ps
Channel 1, mode pulse, repeat 1
start raw utc 13729, coarse 250, frac 0
end raw utc 13729, coarse 287, frac 2048
loop raw utc 0, coarse 12500000, frac 0
fmc-fdelay-status
=================
The program reports the current output status of the four channels,
both in human-readable and raw format. The receives no arguments
besides the usual ``-i`` or ``-d``.
Please note that the tool reads back hardware values, which are already
fixed for calibration delays. For example, this is the output
I get after the previously-shown activation command, that was for
13729 + 2 microseconds:::
spusa.root# ./tools/fmc-fdelay-status
Channel 1, mode already-triggered, repeat 1
start time 13729:000,001,961,814 ps
end time 13729:000,002,261,814 ps
loop time 0:100,000,000,000 ps
Channel 1, mode already-triggered, repeat 1
start raw utc 13729, coarse 245, frac 929
end raw utc 13729, coarse 282, frac 2977
loop raw utc 0, coarse 12500000, frac 0
[...]
The difference in value depends on the ``delay-offset`` value for
the channel, according to calibration.
===============
Troubleshooting
===============
This chapters lists a few errors that may happen and how to deal with
them.
make modules_install misbehaves
===============================
The command ``sudo make modules_install`` may place the modules in the wrong
directory or fail with an error like:::
make: \*\*\* /lib/modules/2.6.37+/build: No such file or directory.
This happens when you compiled by setting ``LINUX=`` and your
*sudo* is not propagating the environment to its child processes.
In this case, you should run this command instead::
sudo make modules_install LINUX=$LINUX
Version Mismatch
================
The *fdelay* library may report a version mismatch like this:::
spusa# ./lib/fmc-fdelay-board-time get
fdelay_init: version mismatch, lib(1) != drv(2)
./lib/fmc-fdelay-board-time: fdelay_init(): Input/output error
This reports a difference in the way ZIO attributes are laid out, so user
space may exchange wrong data in the ZIO control block, or may try to
access inexistent files in */sys*. I suggest recompiling both the kernel
driver and user space from a single release of the source package.
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