Commit aac876d9 authored by Federico Vaga's avatar Federico Vaga

Merge branch 'release/v2.5.3' into master

parents 984ce2b4 b10bbbb7
......@@ -2,10 +2,11 @@
~*
*.a
*.so
GPATH
GRTAGS
GTAGS
Makefile.specific
.*
__pycache__
compile_commands.json
\#*\#
.depend
This diff is collapsed.
......@@ -7,5 +7,17 @@
SPDX-License-Identifier: LGPL-3.0-or-later
"""
from .PyAdcLib import PyAdcConf, PyAdcBuf, PyAdcTimestamp, \
PyAdcAbstract, PyFmcAdc100m14b4ch, PyAdcZioFake, PyAdcGenericFake, \
timeval
__all__ = (
"PyAdcConf",
"PyAdcBuf",
"PyAdcTimestamp",
"PyAdcAbstract",
"PyFmcAdc100m14b4ch",
"PyAdcZioFake",
"PyAdcGenericFake",
"timeval",
)
......@@ -3,7 +3,7 @@
from distutils.core import setup
setup(name='PyAdcLib',
version='1.0',
version='2.5.3',
description='Python Module to handle ADC lib devices',
author='Milosz Malczak, Federico Vaga',
author_email='milosz.malczak@cern.ch, federico.vaga@cern.ch',
......
......@@ -17,9 +17,11 @@
# 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('.'))
import os
import sys
sys.path.append(os.path.abspath('../PyAdcLib'))
sys.path.append(os.path.abspath('../lib'))
# -- General configuration ------------------------------------------------
......@@ -59,9 +61,9 @@ author = 'Federico Vaga <federico.vaga@cern.ch>'
# built documents.
#
# The short X.Y version.
version = '2.2'
version = '2.5'
# The full version, including alpha/beta/rc tags.
release = '2.2.0'
release = '2.5.3'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
......
......@@ -28,6 +28,7 @@ The `ADC library`_ project developed on the `Open Hardware Repository`_.
library-user
library-devel
library-api
python-module
tools-adc-acq
tools-example
......
The Python Module: PyAdcLib
===========================
The *adc-lib* Python module (*PyAdcLib*) is a Python module that wraps
the *adc-lib* library described in :doc:`library-user`.
Most of the features that the Linux library provides are as well
provided by the PyAdcLib module.
Installation
============
Requirements
------------
PyAdcLib depends on:
- Python 3.x;
- Python ctype
- adc-lib library ``libadc.so`` installed;
.. note::
The module has been tested with Python 3.5. In principle it should work
as well on any 3.x version. Compatibility with Python 2.7 has not been
verified. Open an issue if you find Python version incompatibilities.
Install
-------
You can use the Makefile to install PyAdcLib module::
cd /path/to/adc-lib/PyAdcLib
make install
Alternatively, you can use the *distutil* script that takes care of the
module installation in your Python environment::
cd /path/to/adc-lib/PyAdcLib
python setup.py install
On a successful installation you should be able to import PyAdcLib::
import PyAdcLib
The installation is not mandatory. What is really important is that
both the shared object library and the Python module are visible to
the Python interpreter. You can use the environment variables
``PYTHONPATH`` and ``LD_LIBRARY_PATH`` to make them visible::
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path/to/adc-lib
export PYTHONPATH=$PYTHONPATH:/path/to/adc-lib/PyAdcLib
python3
>>> import PyAdcLib
Distribution
------------
If you want to create a package for the distribution of this module, you
can use the ``sdist`` command::
cd /path/to/adc-lib/PyAdcLib
python setup.py sdist
This will create the dist directory in which you will find an archive
corresponding to the version declared in the setup.py script.
.. _`sw:lnx:py:use`:
PyAdcLib Basic Usage
====================
The usage of this module is quite straight forward. The first thing
you have to to do is to create an instance for the device you need.
The available devices are:
- :py:class:`PyAdcLib.PyFmcAdc100m14b4ch`,
- :py:class:`PyAdcLib.PyAdcZioFake`,
- :py:class:`PyAdcLib.PyAdcGenericFake`,
For example:::
import PyAdcLib
adc = PyAdcLib.PyFmcAdc100m14b4ch(2)
At this point it should be enough to have a look at :ref:`sw:lnx:py:api`
to start using the object.
.. _`sw:lnx:py:api`:
The PyAdcLib API
====================
Here you can find the complete *PyAdcLib* API. PyAdcLib exports a set
of objects used to handle components. Then, it exports a set of
*ctype* data structures used to exchange information with the ADC library
layers.
.. note::
Since this Python module is nothing more than a wrapper on top of
a C library, we suggest you to have a look at :doc:`library-user`
for a better understanding of this API
PyAdcLib Objects
----------------
.. autoclass:: PyAdcLib.PyFmcAdc100m14b4ch
:members:
.. autoclass:: PyAdcLib.PyAdcZioFake
:members:
.. autoclass:: PyAdcLib.PyAdcGenericFake
:members:
.. autoclass:: PyAdcLib.PyAdcAbstract
:members:
PyAdcLib Data Structures
------------------------
.. autoclass:: PyAdcLib.PyAdcConf
:members:
.. autoclass:: PyAdcLib.PyAdcBuf
:members:
.. autoclass:: PyAdcLib.PyAdcTimestamp
:members:
.. autoclass:: PyAdcLib.timeval
:members:
......@@ -6,7 +6,8 @@
-include Makefile.specific
# include parent_common.mk for buildsystem's defines
REPO_PARENT ?= ../..
IGNORE_CPU_SUFFIX := y
REPO_PARENT ?=
-include $(REPO_PARENT)/parent_common.mk
ZIO ?= $(HOME)/git/zio
......
from PyAdcLib import ADC_Generic
class AdcGenericFake(ADC_Generic):
BOARD_NAME = b"adc-genericfake"
def __init__(self, devid):
super(AdcGenericFake, self).__init__(devid)
This diff is collapsed.
from .PyAdcLib import ADC_Generic
class FmcAdc100m14b4ch(ADC_Generic):
BOARD_NAME = b"fmc-adc-100m14b4cha"
ADC_CONF_100M14B4CHA_CHN_RANGE_N = 3
ADC_CONF_100M14B4CHA_CHN_RANGE_OPEN_DRAIN = 0
ADC_CONF_100M14B4CHA_CHN_RANGE_100mV = 0x23
ADC_CONF_100M14B4CHA_CHN_RANGE_1V = 0x11
ADC_CONF_100M14B4CHA_CHN_RANGE_10V = 0x45
ADC_CONF_100M14B4CHA_CHN_RANGE_100mV_CAL = 0x42
ADC_CONF_100M14B4CHA_CHN_RANGE_1V_CAL = 0x40
ADC_CONF_100M14B4CHA_CHN_RANGE_10V_CAL = 0x44
ADC_CONF_100M14B4CHA_BUF_KMALLOC = 0
ADC_CONF_100M14B4CHA_BUF_VMALLOC = 1
ADC_CONF_100M14B4CHA_BUF_TYPE = 0
ADC_CONF_100M14B4CHA_TRG_SW_EN = 1
ADC_CONF_100M14B4CHA_ACQ_MSHOT_MAX = 2
ADC_CONF_100M14B4CHA_BUF_SIZE_KB = 3
ADC_CONF_100M14B4CHA_TRG_ALT_EN = 4
__ADC_CONF_100M14B4CHA_LAST_INDEX = 5
def __init__(self, devid):
super(FmcAdc100m14b4ch, self).__init__(devid)
from PyAdcLib import ADC_Generic
class AdcZioFake(ADC_Generic):
BOARD_NAME = b"adc-ziofake"
def __init__(self, devid):
super(AdcZioFake, self).__init__(devid)
"""
SPDX-License-Identifier: GPL-3.0-or-later
SPDX-FileCopyrightText: 2020 CERN
"""
import pytest
from PyAdcLib import *
@pytest.fixture(scope="function")
def adc100m14b4cha():
adc = PyFmcAdc100m14b4ch(pytest.adc_id)
yield adc
adc.acq_stop(0)
@pytest.fixture(scope="function")
def adc100m14b4cha_def_cfg():
adc = PyFmcAdc100m14b4ch(pytest.adc_id)
for ch in range(4):
conf = PyAdcConf(PyAdcConf.ADC_CONF_TYPE_CHN, ch)
conf.value_set(PyAdcConf.ADC_CONF_CHN_RANGE, 0x45)
conf.value_set(PyAdcConf.ADC_CONF_CHN_TERMINATION, 0)
conf.value_set(PyAdcConf.ADC_CONF_CHN_OFFSET, 0)
conf.value_set(PyAdcConf.ADC_CONF_CHN_SATURATION, 0x7FFF)
adc.apply_config(conf, 0)
for ch in range(4):
conf = PyAdcConf(PyAdcConf.ADC_CONF_TYPE_TRG_THR, ch)
conf.value_set(PyAdcConf.ADC_CONF_TRG_THR_ENABLE, 0)
adc.apply_config(conf, 0)
conf = PyAdcConf(PyAdcConf.ADC_CONF_TYPE_TRG_EXT, 0)
conf.value_set(PyAdcConf.ADC_CONF_TRG_EXT_ENABLE, 0)
adc.apply_config(conf, 0)
yield adc
adc.acq_stop(0)
@pytest.fixture(scope="function")
def adc_simple():
adc = PyFmcAdc100m14b4ch(pytest.adc_id)
for ch in range(4):
conf = PyAdcConf(PyAdcConf.ADC_CONF_TYPE_CHN, ch)
conf.value_set(PyAdcConf.ADC_CONF_CHN_RANGE, 0x45)
conf.value_set(PyAdcConf.ADC_CONF_CHN_TERMINATION, 0)
conf.value_set(PyAdcConf.ADC_CONF_CHN_OFFSET, 0)
conf.value_set(PyAdcConf.ADC_CONF_CHN_SATURATION, 0x7FFF)
adc.apply_config(conf, 0)
for ch in range(4):
conf = PyAdcConf(PyAdcConf.ADC_CONF_TYPE_TRG_THR, ch)
conf.value_set(PyAdcConf.ADC_CONF_TRG_THR_ENABLE, 0)
conf.value_set(PyAdcConf.ADC_CONF_TRG_THR_POLARITY, 0)
conf.value_set(PyAdcConf.ADC_CONF_TRG_THR_DELAY, 0)
conf.value_set(PyAdcConf.ADC_CONF_TRG_THR_THRESHOLD, 0)
conf.value_set(PyAdcConf.ADC_CONF_TRG_THR_HYSTERESIS, 0)
adc.apply_config(conf, 0)
conf = PyAdcConf(PyAdcConf.ADC_CONF_TYPE_TRG_EXT, 0)
conf.value_set(PyAdcConf.ADC_CONF_TRG_EXT_ENABLE, 0)
adc.apply_config(conf, 0)
conf = PyAdcConf(PyAdcConf.ADC_CONF_TYPE_TRG_TIM, 0)
conf.value_set(PyAdcConf.ADC_CONF_TRG_TIM_ENABLE, 0)
conf.value_set(PyAdcConf.ADC_CONF_TRG_TIM_SECONDS, 0)
conf.value_set(PyAdcConf.ADC_CONF_TRG_TIM_NANO_SECONDS, 0)
adc.apply_config(conf, 0)
conf = PyAdcConf(PyAdcConf.ADC_CONF_TYPE_ACQ, 0)
conf.value_set(PyAdcConf.ADC_CONF_ACQ_PRE_SAMP, 1)
conf.value_set(PyAdcConf.ADC_CONF_ACQ_POST_SAMP, 2)
conf.value_set(PyAdcConf.ADC_CONF_ACQ_N_SHOTS, 1)
adc.apply_config(conf, 0)
yield adc
adc.acq_stop(0)
def pytest_addoption(parser):
parser.addoption("--type", choices=[PyFmcAdc100m14b4ch.BOARD_NAME],
required=True, help="Fmc ADC type")
parser.addoption("--id", type=lambda x : int(x, 16),
required=True, help="Fmc ADC Identifier")
def pytest_configure(config):
pytest.adc_type = config.getoption("--type")
pytest.adc_id = config.getoption("--id")
"""
SPDX-License-Identifier: GPL-3.0-or-later
SPDX-FileCopyrightText: 2020 CERN
"""
import pytest
import time
from PyAdcLib import PyAdcConf, PyFmcAdc100m14b4ch, timeval
@pytest.fixture(scope="function", params=[1 << i for i in range(14)])
def adc_simple_pattern(adc_simple, request):
adc_simple.pattern_data = request.param
yield adc_simple
adc_simple.pattern_data = None
class TestAdcAcquisitionPattern(object):
def test_adc_acq_poll_fail(self, adc_simple):
"""Test that the poll fails with timeout if there are no triggers"""
conf = PyAdcConf(PyAdcConf.ADC_CONF_TYPE_ACQ, 0)
conf.value_set(PyAdcConf.ADC_CONF_ACQ_N_SHOTS, 1)
adc_simple.apply_config(conf, 0)
timeout = timeval(0,0)
adc_simple.acq_start(PyFmcAdc100m14b4ch.ADC_F_FLUSH,
timeout)
with pytest.raises(OSError):
timeout = timeval(2,0)
adc_simple.acq_poll(0, timeout)
@pytest.mark.parametrize("nshots", range(1, 10))
def test_adc_acq_poll(self, adc_simple, nshots):
conf = PyAdcConf(PyAdcConf.ADC_CONF_TYPE_ACQ, 0)
conf.value_set(PyAdcConf.ADC_CONF_ACQ_N_SHOTS, nshots)
adc_simple.apply_config(conf, 0)
timeout = timeval(0,0)
adc_simple.acq_start(PyFmcAdc100m14b4ch.ADC_F_FLUSH,
timeout)
for i in range(nshots):
adc_simple.trigger_fire()
time.sleep(0.1)
timeout = timeval(10,0)
adc_simple.acq_poll(0, timeout)
@pytest.mark.parametrize("pre_samples,post_samples",
[(10**x, 10**y) for x in range(1, 3) for y in range(1, 3)])
@pytest.mark.parametrize("nshots", range(1, 10))
def test_adc_acq_basic(self, adc_simple_pattern,
pre_samples, post_samples, nshots):
"""Test that we can get"""
conf = PyAdcConf(PyAdcConf.ADC_CONF_TYPE_ACQ, 0)
conf.value_set(PyAdcConf.ADC_CONF_ACQ_PRE_SAMP, pre_samples)
conf.value_set(PyAdcConf.ADC_CONF_ACQ_POST_SAMP, post_samples)
conf.value_set(PyAdcConf.ADC_CONF_ACQ_N_SHOTS, nshots)
adc_simple_pattern.apply_config(conf, 0)
nsamples = pre_samples + post_samples
buf = adc_simple_pattern.request_buffer(nsamples * nshots, None, 0)
adc_simple_pattern.acq_start(PyFmcAdc100m14b4ch.ADC_F_FLUSH,
timeval(0, 0))
for n in range(nshots):
time.sleep(1e-8 * pre_samples)
adc_simple_pattern.trigger_fire()
adc_simple_pattern.acq_poll(0, timeval(10, 0))
adc_simple_pattern.fill_buffer(buf, 0, timeval(10, 0))
assert buf.contents.nsamples == nsamples
pattern = adc_simple_pattern.pattern_data
for n in range(nshots):
for chan in range(4):
for s in range(nsamples):
assert buf.get_sample(chan, s) >> 2 == pattern, \
buf.contents.data[:nsamples]
adc_simple_pattern.release_buffer(buf, None)
This diff is collapsed.
"""
SPDX-License-Identifier: GPL-3.0-or-later
SPDX-FileCopyrightText: 2020 CERN
"""
import pytest
import time
from PyAdcLib import PyAdcConf, PyFmcAdc100m14b4ch
class TestAdcTime(object):
def test_time_flows(self, adc100m14b4cha):
"""Just check that the time flows more or less correctly second by
second for a minute"""
conf = PyAdcConf(PyAdcConf.ADC_CONF_TYPE_BRD, 0)
conf.mask_set(PyAdcConf.ADC_CONF_UTC_TIMING_BASE_S)
adc100m14b4cha.retrieve_config(conf)
t_prev = conf.value_get(PyAdcConf.ADC_CONF_UTC_TIMING_BASE_S)
for i in range(20):
time.sleep(1)
adc100m14b4cha.retrieve_config(conf)
sec = conf.value_get(PyAdcConf.ADC_CONF_UTC_TIMING_BASE_S)
assert t_prev + 1 == sec
t_prev = sec
This diff is collapsed.
# SPDX-License-Identifier: GPL-3.0-or-later
# SPDX-FileCopyrightText: 2020 CERN
[pytest]
addopts = -v -p no:cacheprovider
\ No newline at end of file
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