Commit ee979f76 authored by Evangelia Gousiou's avatar Evangelia Gousiou

added relevant files from pts repo

parents
Production Test Suite, automatized tests for OHWR boards.
Copyright (C) 2011 CERN
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
This is Production Test Suite project.
Supporting automated hardware testing at BE/CO/HT
since 2011 or even less
License: GPL v2 or later
# Copyright INCAA Computers, 2012
# Author: Bert Gooijer <bert.gooijer@incaacomputers.com>
# Licence: GPL v2 or later.
# Website: http://www.ohwr.org
import os
class usbtmc:
def __init__(self, device):
print("Opening: %s" % device)
self.device = device
self.FILE = os.open(device, os.O_RDWR)
def write(self, command):
os.write(self.FILE, command)
def read(self):
return os.read(self.FILE, 4000)
def getName(self):
self.write("*IDN?")
return self.read()
def sendReset(self):
self.write("*RST")
def close(self):
os.close(self.FILE)
class PendulumCNT91:
def __init__(self, device):
self.meas = usbtmc(device)
self.name = self.meas.getName()
print self.name
def write(self, command):
self.meas.write(command)
def read(self):
return self.meas.read()
def reset(self):
self.meas.sendReset()
def close(self):
self.meas.close()
\ No newline at end of file
# -*- coding: utf-8 -*-
__author__ = "Johannes Hölzl <johannes.hoelzl@gmx.de>"
__license__ = "GNU LGPL"
This diff is collapsed.
# -*- coding: utf-8 -*-
# Copyright (c) 2007 Johannes Hölzl <johannes.hoelzl@gmx.de>
#
# This library is covered by the GNU LGPL, read LICENSE for details.
import cp210x
from cp210x import from_binary, to_binary, iif, VALUES
__all__ = ['EEPROM', 'HexFileError']
POS_BAUDRATE_TABLE = 0x0000
POS_PART_NUMBER = 0x01FF
POS_PRODUCT_STRING = 0x0208
POS_SERIAL_NUMBER = 0x0307
POS_PRODUCT_ID = 0x0390
POS_VENDOR_ID = 0x0392
POS_VERSION = 0x0394
POS_CFG_ATTRIBUTES = 0x03A1
POS_MAX_POWER = 0x03A2
POS_VENDOR_STRING = 0x03C3
POS_LOCK_VALUE = 0x03FF
class HexFileError(StandardError):
pass
def checksum(line):
return sum(ord(c) for c in line) & 0xFF
def _int_value(position, size, read=lambda x:x, write=lambda x:x):
def get(self):
return read(from_binary(self.get(position, size)))
def set(self, value):
self.set(position, to_binary(write(value), size))
return property(get, set)
def _str_value(position, max_size):
def get(self):
size = from_binary(self.get(position, 1))
assert size <= (max_size + 2) and size >= 2
assert self.get(position + 1, 1) == '\x03', "Missing 0x03 at %04X" % (position + 1)
return self.get(position + 2, size - 2).decode('utf-16-le')
def set(self, value):
encoded = value.encode('utf-16-le')
assert len(encoded) <= max_size
self.set(position, chr(len(encoded) + 2) + '\x03' + encoded)
return property(get, set)
class EEPROM(object):
START_ADDRESS = 0x3600
def __init__(self, content=None):
if isinstance(content, str) or content is None:
assert content is None or len(content) == cp210x.SIZE_EEPROM
self.content = content
elif isinstance(content, cp210x.Cp210xProgrammer):
self.content = content.get_eeprom_content()
else:
self.parse_hex_file(content.read())
def write_to_cp210x(self, cp210xDevice):
cp210xDevice.set_eeprom_content(self.content)
def parse_hex_file(self, hex_content):
self.content = ''
address = self.START_ADDRESS
for tag in hex_content.split('\n'):
if not tag.startswith(':'):
raise HexFileError("Line doesn't start with ':'")
try:
content = tag[1:].decode('hex')
except TypeError:
raise HexFileError("Hex data expected")
if len(content) < 5:
raise HexFileError("Line to short")
if checksum(content) != 0:
raise HexFileError("Checksum error")
size = from_binary(content[0])
tag_address = from_binary(content[1:3], le=False)
tag_type = from_binary(content[3:4])
line = content[4:-1]
if tag_type == 0x00:
if tag_address != address:
raise HexFileError("Expected address %04X but found %04X"
% (address, tag_address))
self.content += line
address += len(line)
elif tag_type == 0x01:
if size != 0 or len(line) != 0:
raise HexFileError("Defekt end tag")
break
else:
raise HexFileError("Unknown tag type %02X" % tag_type)
def build_hex_file(self):
for tag_start in range(0, len(self.content), 0x10):
line = self.content[tag_start:tag_start+0x10]
address = self.START_ADDRESS + tag_start
tag = (to_binary(len(line), 1) +
to_binary(address, le=False) +
'\x00' +
line)
cs = checksum(tag)
if cs == 0:
tag += '\x00'
else:
tag += chr(0x100 - cs)
yield ":%s\n" % tag.encode('hex')
yield ":00000001FF\n"
def write_hex_file(self, f):
if isinstance(f, str):
f = file(f, 'wb')
do_close = True
else:
do_close = False
for line in self.build_hex_file():
f.write(line)
if do_close:
f.close()
def read_hex_file(self, f):
if isinstance(f, str):
f = file(f, 'rb')
do_close = True
else:
do_close = False
self.parse_hex_file(f.read())
if do_close:
f.close()
def get(self, pos, length):
return self.content[pos:pos+length]
def set(self, pos, data):
self.content = (self.content[:pos] +
data +
self.content[pos + len(data):])
def _get_baudrate_table(self):
dat = self.get(POS_BAUDRATE_TABLE, cp210x.SIZE_BAUDRATE_TABLE)
return [cp210x.parse_baudrate_cfg(dat[pos:pos+cp210x.SIZE_BAUDRATE_CFG])
for pos in range(0, cp210x.SIZE_BAUDRATE_TABLE,
cp210x.SIZE_BAUDRATE_CFG)]
def _set_baudrate_table(self, baudrates):
assert len(baudrates) == cp210x.SIZE_BAUDRATES
self.set(POS_BAUDRATE_TABLE,
''.join(cp210x.build_baudrate_cfg(*cfg) for cfg in baudrates))
baudrate_table = property(_get_baudrate_table, _set_baudrate_table)
product_string = _str_value(POS_PRODUCT_STRING, cp210x.SIZE_PRODUCT_STRING)
serial_number = _str_value(POS_SERIAL_NUMBER, cp210x.SIZE_SERIAL_NUMBER)
part_number = _int_value(POS_PART_NUMBER, 1)
product_id = _int_value(POS_PRODUCT_ID, 2)
vendor_id = _int_value(POS_VENDOR_ID, 2)
version = _int_value(POS_VERSION, 2,
cp210x.from_bcd2, cp210x.to_bcd2)
bus_powered = _int_value(POS_CFG_ATTRIBUTES, 1,
lambda a: bool(a & 0x40),
lambda a: iif(a, 0xC0, 0x80))
max_power = _int_value(POS_MAX_POWER, 1, lambda p: p*2, cp210x.to_div2)
vendor_string = _str_value(POS_VENDOR_STRING, cp210x.SIZE_VENDOR_STRING)
locked = _int_value(POS_LOCK_VALUE, 1,
lambda l: l == cp210x.LCK_LOCKED,
lambda b: iif(b, cp210x.LCK_LOCKED,
cp210x.LCK_UNLOCKED))
def get_values(self):
return dict((name, getattr(self, name)) for name, type in VALUES)
def set_values(self, values):
for name, value in values.items():
setattr(self, name, value)
# Python interface for "usb.h" version 0.1.4.4.4
#
# Copyright (c) 2005 Robert Hoelzl <robert.hoelzl@gmx.de>
# Copyright (c) 2007 Johannes Hoelzl <johannes.hoelzl@gmx.de>
#
# This library is covered by the GNU LGPL, read LICENSE for details.
from ctypes import *
import sys
class LibUsbNotInstalled(OSError):
pass
try:
if sys.platform == 'darwin':
PATH_MAX = 1024
dll=cdll.LoadLibrary("libusb.dylib")
elif sys.platform == 'linux2':
PATH_MAX = 4096
dll=cdll.LoadLibrary("libusb.so")
else:
raise NotImplementedError("Platform %s not supported by usb.py" % sys.platform)
except OSError:
raise LibUsbNotInstalled()
# helper functions
def func(f, *args, **retval):
f.restype = retval.get('retval', None)
f.argtypes = args
if retval.has_key('rename'): globals()[retval['rename']] = f
else: globals()[f.__name__[4:]] = f
# constants
CLASS_PER_INTERFACE = 0
USB_CLASS_AUDIO = 1
CLASS_COMM = 2
CLASS_HID = 3
CLASS_PRINTER = 7
CLASS_PTP = 6
CLASS_MASS_STORAGE = 8
CLASS_HUB = 9
CLASS_DATA = 10
CLASS_VENDOR_SPEC = 0xff
DT_DEVICE = 0x01
DT_CONFIG = 0x02
DT_STRING = 0x03
DT_INTERFACE = 0x04
DT_ENDPOINT = 0x05
DT_HID = 0x21
DT_REPORT = 0x22
DT_PHYSICAL = 0x23
DT_HUB = 0x29
DT_DEVICE_SIZE = 18
DT_CONFIG_SIZE = 9
DT_INTERFACE_SIZE = 9
DT_ENDPOINT_SIZE = 7
DT_ENDPOINT_AUDIO_SIZE = 9 # Audio extension
DT_HUB_NONVAR_SIZE = 7
class descriptor_header(Structure): _fields_ = [
("bLength", c_uint8),
("bDescriptorType", c_uint8) ]
class string_descriptor(Structure): _fields_ = [
("bLength", c_uint8),
("bDescriptorType", c_uint8),
("wData", c_uint*1) ]
class hid_descriptor(Structure): _fields_ = [
("bLength", c_uint8),
("bDescriptorType", c_uint8),
("bcdHID", c_uint16),
("bCountryCode", c_uint8),
("bNumDescriptors", c_uint8) ]
MAXENDPOINTS = 32
class endpoint_descriptor(Structure): _fields_ = [
("bLength", c_uint8),
("bDescriptorType", c_uint8),
("bEndpointAddress", c_uint8),
("bmAttributes", c_uint8),
("wMaxPacketSize", c_uint16),
("bInterval", c_uint8),
("bRefresh", c_uint8),
("bSynchAddress", c_uint8),
("extra", POINTER(c_uint8)),
("extralen", c_int) ]
ENDPOINT_ADDRESS_MASK = 0x0f # in bEndpointAddress
ENDPOINT_DIR_MASK = 0x80
ENDPOINT_TYPE_MASK = 0x03 # in bmAttributes
ENDPOINT_TYPE_CONTROL = 0
ENDPOINT_TYPE_ISOCHRONOUS = 1
ENDPOINT_TYPE_BULK = 2
ENDPOINT_TYPE_INTERRUPT = 3
MAXINTERFACES = 32
class interface_descriptor(Structure): _fields_ = [
("bLength", c_uint8),
("bDescriptorType", c_uint8),
("bInterfaceNumber", c_uint8),
("bAlternateSetting", c_uint8),
("bNumEndpoints", c_uint8),
("bInterfaceClass", c_uint8),
("bInterfaceSubClass", c_uint8),
("bInterfaceProtocol", c_uint8),
("iInterface", c_uint8),
("endpoint", POINTER(endpoint_descriptor)),
("extra", POINTER(c_uint8)),
("extralen", c_int) ]
MAXALTSETTING = 128 # Hard limit
class interface(Structure): _fields_ = [
("altsetting", POINTER(interface_descriptor)),
("num_altsetting", c_int) ]
MAXCONFIG = 8
class config_descriptor(Structure): _fields_ = [
("bLength", c_uint8),
("bDescriptorType", c_uint8),
("wTotalLength", c_uint16),
("bNumInterfaces", c_uint8),
("bConfigurationValue", c_uint8),
("iConfiguration", c_uint16),
("bmAttributes", c_uint8),
("MaxPower", c_uint8),
("interface", POINTER(interface)),
("extra", POINTER(c_uint8)), # Extra descriptors
("extralen", c_int) ]
class device_descriptor(Structure): _fields_ = [
("bLength", c_uint8),
("bDescriptorType", c_uint8),
("bcdUSB", c_uint16),
("bDeviceClass", c_uint8),
("bDeviceSubClass", c_uint8),
("bDeviceProtocol", c_uint8),
("bMaxPacketSize0", c_uint8),
("idVendor", c_uint16),
("idProduct", c_uint16),
("bcdDevice", c_uint16),
("iManufacturer", c_uint8),
("iProduct", c_uint8),
("iSerialNumber", c_uint8),
("bNumConfigurations", c_uint8) ]
class ctrl_setup(Structure): _fields_ = [
("bRequestType", c_uint8),
("bRequest", c_uint8),
("wValue", c_uint16),
("wIndex", c_uint16),
("wLength", c_uint16) ]
REQ_GET_STATUS = 0x00
REQ_CLEAR_FEATURE = 0x01
# 0x02 is reserved
REQ_SET_FEATURE = 0x03
# 0x04 is reserved
REQ_SET_ADDRESS = 0x05
REQ_GET_DESCRIPTOR = 0x06
REQ_SET_DESCRIPTOR = 0x07
REQ_GET_CONFIGURATION = 0x08
REQ_SET_CONFIGURATION = 0x09
REQ_GET_INTERFACE = 0x0A
REQ_SET_INTERFACE = 0x0B
REQ_SYNCH_FRAME = 0x0C
TYPE_STANDARD = (0x00 << 5)
TYPE_CLASS = (0x01 << 5)
TYPE_VENDOR = (0x02 << 5)
TYPE_RESERVED = (0x03 << 5)
RECIP_DEVICE = 0x00
RECIP_INTERFACE = 0x01
RECIP_ENDPOINT = 0x02
RECIP_OTHER = 0x03
ENDPOINT_IN = 0x80
ENDPOINT_OUT = 0x00
# Error codes
ERROR_BEGIN = 500000
#if 1
#define USB_LE16_TO_CPU(x) do { x = ((x & 0xff) << 8) | ((x & 0xff00) >> 8); } while(0)
#else
#define USB_LE16_TO_CPU(x)
#endif
device_p = POINTER("device")
bus_p = POINTER("bus")
class device(Structure): _fields_ = [
("next", device_p),
("prev", device_p),
("filename", c_char*(PATH_MAX + 1)),
("bus", bus_p),
("descriptor", device_descriptor),
("config", POINTER(config_descriptor)),
("dev", c_void_p), # Darwin support
("devnum", c_char),
("num_children", c_uint8),
("children", POINTER(device_p)) ]
SetPointerType(device_p, device)
class bus(Structure): _fields_ = [
("next", bus_p),
("prev", bus_p),
("dirname", c_char*(PATH_MAX + 1)),
("devices", device_p),
("location", c_uint),
("root_dev", device_p) ]
SetPointerType(bus_p, bus)
dev_handle_p = c_void_p
func(dll.usb_open, device_p, retval=dev_handle_p, rename="_open")
func(dll.usb_close, dev_handle_p, retval=c_int)
func(dll.usb_get_string, dev_handle_p, c_int, c_int, c_char_p, c_int, retval=c_int)
func(dll.usb_get_string_simple, dev_handle_p, c_int, c_char_p, c_int, retval=c_int)
func(dll.usb_get_descriptor_by_endpoint, dev_handle_p, c_int, c_uint8, c_uint8, c_void_p, c_int, retval=c_int)
func(dll.usb_get_descriptor, dev_handle_p, c_uint8, c_uint8, c_void_p, c_int, retval=c_int)
func(dll.usb_bulk_write, dev_handle_p, c_int, c_char_p, c_int, c_int, retval=c_int)
func(dll.usb_bulk_read, dev_handle_p, c_int, c_char_p, c_int, c_int, retval=c_int)
func(dll.usb_interrupt_write, dev_handle_p, c_int, c_char_p, c_int, c_int, retval=c_int)
func(dll.usb_interrupt_read, dev_handle_p, c_int, c_char_p, c_int, c_int, retval=c_int)
func(dll.usb_control_msg, dev_handle_p, c_int, c_int, c_int, c_int, c_char_p, c_int, c_int, retval=c_int)
func(dll.usb_set_configuration, dev_handle_p, c_int, retval=c_int)
func(dll.usb_claim_interface, dev_handle_p, c_int, retval=c_int)
func(dll.usb_release_interface, dev_handle_p, c_int, retval=c_int)
func(dll.usb_set_altinterface, dev_handle_p, c_int, retval=c_int)
func(dll.usb_resetep, dev_handle_p, c_uint16, retval=c_int)
func(dll.usb_clear_halt, dev_handle_p, c_uint16, retval=c_int)
func(dll.usb_reset, dev_handle_p, retval=c_int)
func(dll.usb_strerror, retval=c_char_p)
func(dll.usb_init)
func(dll.usb_set_debug, c_int)
func(dll.usb_find_busses, retval=c_int)
func(dll.usb_find_devices, retval=c_int)
func(dll.usb_device, dev_handle_p, retval=device_p, rename="get_device")
func(dll.usb_get_busses, retval=bus_p)
func(dll.usb_detach_kernel_driver_np, dev_handle_p, c_int, retval=c_int)
# workaround for bug in ctypes 0.9.6 (cannot create functions with c_void_p as retval)
def open(dev):
return cast(_open(dev), dev_handle_p)
# -*- coding: utf-8 -*-
# Copyright (c) 2007 Johannes Hölzl <johannes.hoelzl@gmx.de>
#
# This library is covered by the GNU LGPL, read LICENSE for details.
# For documentation of the baudrate table see:
#
# [AN205] Silicon Labs Application Note 205 Rev. 0.3
# http://www.silabs.com/public/documents/tpub_doc/anote/Microcontrollers/Interface/en/an205.pdf
import re
from ConfigParser import ConfigParser
import cp210x
from cp210x import VALUES, SIZE_BAUDRATES
__all__ = ['read_file', 'write_file', 'update_values', 'PrescalerIsZero',
'ValuesFileError']
class ValuesError(StandardError):
pass
class PrescalerIsZero(ValuesError):
pass
class ValuesFileError(ValuesError):
pass
version_pattern = re.compile(r'^\s*(\d\d?)\.(\d\d?)\s*$')
def read_version(s):
match = version_pattern.match(s)
if match is None:
raise ValueError("Version does not match 'xx.yy'")
return (int(match.group(1)), int(match.group(2)))
def write_version(v):
return "%d.%02d" % v
def read_hex(s):
return int(s.strip(), 16)
def write_hex(num):
return "%04X" % num
def write_bool(b):
if b:
return 'yes'
else:
return 'no'
def read_bool(s):
s = s.strip().lower()
if s not in ['true', 'yes', 'false', 'no']:
raise ValueError("Boolean must be either 'true', 'yes', 'false' or 'no'.")
return s in ['true', 'yes']
def read_baudrate_info(s):
values = s.split(',')
if len(values) != 3:
raise ValueError("Baudrate info must be three comma-separated items")
try:
baudgen = read_hex(values[0])
except ValueError:
raise ValueError("The first baudrate info must be a hex-value")
try:
timer0 = read_hex(values[1])
except ValueError:
raise ValueError("The second baudrate info must be a hex-value")
try:
prescale = int(values[2])
except ValueError:
raise ValueError("The thirdbaudrate info must be a number")
return (baudgen, timer0, prescale)
TYPES = {
'boolean': (read_bool, write_bool),
'int': (int, str),
'id': (read_hex, write_hex),
'string': (str, str),
'version': (read_version, write_version),
}
def read_file(fp):
cp = ConfigParser()
if isinstance(fp, str):
cp.read([fp])
else:
cp.readfp(fp)
values = {}
for name, type in VALUES:
if name is 'baudrate_table':
continue
reader, _ = TYPES[type]
if cp.has_option('usb device', name):
try:
values[name] = reader(cp.get('usb device', name))
except ValueError, err:
raise ValuesFileError("Key '%s': %s" % (name, str(err)))
if cp.has_section('baudrate table'):
baudrate_table = []
for name, value in cp.items('baudrate table'):
try:
baudrate = int(name)
except ValueError:
raise ValuesFileError("Key names in 'baudrate table' must be"
" baudrate numbers.")
try:
baudrate_table.append(read_baudrate_info(value) + (baudrate, ))
except ValueError, err:
raise ValuesFileError("Wrong baudrate info %i: %s"
% (baudrate, str(err)))
baudrate_table.sort(key=(lambda i: i[3]), reverse=True)
values['baudrate_table'] = baudrate_table
return values
def write_file(fp, values):
fp.write("[usb device]\n")
for name, type in VALUES:
if name == 'baudrate_table':
continue
_, writer = TYPES[type]
if name in values:
fp.write("%s = %s\n" % (name, writer(values[name])))
if 'baudrate_table' in values:
fp.write("\n")
fp.write("[baudrate table]\n")
for (baudgen, timegen, prescaler,
baudrate) in sorted(values['baudrate_table'], key=(lambda i: i[3]),
reverse=True):
fp.write("%7d = %04X, %04X, %d # %s\n"
% (baudrate, baudgen, timegen, prescaler,
show_baudrate(baudgen, timegen, prescaler)))
def calc_baudrate(baudgen, timegen, prescaler):
# This formulas are from AN205 page 5.
if prescaler == 0:
raise PrescalerIsZero("Prescaler is 0")
baudrate = (24000000. / prescaler) / (0x10000 - baudgen)
return (baudrate, (0x10000 - timegen) * 2)
def show_baudrate(baudgen, timegen, prescaler):
try:
baudrate, timeout = calc_baudrate(baudgen, timegen, prescaler)
except PrescalerIsZero:
return "Wrong data, Prescaler is 0."
if timeout >= 1000:
timeout = "%1.3f ms" % (float(timeout) / 1000)
else:
timeout = "%d us" % timeout
if baudrate is None:
return ", %s" % (baudrate, timeout)
else:
return "%7.0f Baud, %s" % (baudrate, timeout)
def update_values(v, new, dev):
old_baudrate_table = v.get('baudrate_table')
new_baudrate_table = new.get('baudrate_table')
v.update(new)
# update baudrate table
# it is needed, that the baudrate table has 32 entries when it is written
# to the eeprom or device.
if ((old_baudrate_table is not None or new_baudrate_table is not None) and
(new_baudrate_table is None or
len(new_baudrate_table) < SIZE_BAUDRATES)):
if old_baudrate_table is not None:
if len(old_baudrate_table) < SIZE_BAUDRATES:
baudrate_table = old_baudrate_table
else:
baudrate_table = list(merge_baudrate_table(dev.baudrate_table,
old_baudrate_table))
else:
baudrate_table = dev.baudrate_table
if new_baudrate_table:
baudrate_table = list(merge_baudrate_table(baudrate_table,
new_baudrate_table))
v['baudrate_table'] = baudrate_table
def merge_baudrate_table(old, new):
for (old_info, (start, stop)) in zip(old, REQUEST_BAUDRATE_RANGES):
for baudgen, timer, prescaler, baudrate in new:
if ((start is None or baudrate <= start) and
baudrate >= stop):
yield (baudgen, timer, prescaler, baudrate)
break
else:
yield old_info
REQUEST_BAUDRATE_RANGES = [
# The table data is from AN205 Table 1 on page 1.
# Start End Default Baudrate
(None, 2457601), # Undefined
(2457600, 1474561), # Undefined
(1474560, 1053258), # Undefined
(1053257, 670255), # 921600
( 670254, 567139), # 576000
( 567138, 491521), # 500000
( 491520, 273067), # 460800
( 273066, 254235), # 256000
( 254234, 237833), # 250000
( 237832, 156869), # 230400
( 156868, 129348), # 153600
( 129347, 117029), # 128000
( 117028, 77609), # 115200
( 77608, 64112), # 76800
( 64111, 58054), # 64000
( 58053, 56281), # 57600
( 56280, 51559), # 56000
( 51558, 38602), # 51200
( 38601, 28913), # 38400
( 28912, 19251), # 28800
( 19250, 16063), # 19200
( 16062, 14429), # 16000
( 14428, 9613), # 14400
( 9612, 7208), # 9600
( 7207, 4804), # 7200
( 4803, 4001), # 4800
( 4000, 2401), # 4000
( 2400, 1801), # 2400
( 1800, 1201), # 1800
( 1200, 601), # 1200
( 600, 301), # 600
( 300, 57), # 300
]
#! /usr/bin/env python
# coding: utf8
# Copyright CERN, 2011
# Author: Matthieu Cattin <matthieu.cattin@cern.ch>
# Licence: GPL v2 or later.
# Website: http://www.ohwr.org
import sys
import rr
import time
import os
import re
from ctypes import *
from ptsexcept import *
from cp210x import usb, valuefile, cp210x
from cp210x.eeprom import EEPROM
"""
cp210x_eeprom: Access to USB-UART bridge CP2103 EEPROM
Note: The EEPROM is used to store calibration data.
The data is stored as a string in the "Product String".
Format example: "234.45, 163.08, 174.98, 205.81"
"""
CALIBR_CHANNELS = ['ch1-ch2', 'ch1-ch3', 'ch1-ch4', 'ch1-ch5']
class CP210xEepromOperationError(Exception):
def __init__(self, msg):
self.msg = msg
def __str__(self):
return ("CP210x EEPROM: %s" %(self.msg))
class CCP210x_Eeprom:
def __init__(self, vid, pid):
usb.init()
usb_patterns = []
vid = int(vid, 16)
pid = int(pid, 16)
usb_patterns.append(dict(idVendor=vid, idProduct=pid))
self.dev = [item for item in cp210x.Cp210xProgrammer.list_devices(usb_patterns)]
self.dev = self.dev[0]
def get_calibr_data(self):
self.dev.open()
try:
eeprom = EEPROM(self.dev)
except:
raise CP210xEepromOperationError('Cannot open device.')
finally:
self.dev.close()
eeprom_value = eeprom.get_values()
product_string = eeprom_value['product_string']
#print "Product string: \"%s\"" % product_string
calibr_string_list = product_string.split(' ')
if len(calibr_string_list) != 4:
raise CP210xEepromOperationError('Product string has the wrong format.')
calibr_data = {}
for i in range(len(calibr_string_list)):
pattern = r'\b[0-9]{3}\.[0-9]{2}\b'
if re.search(pattern, calibr_string_list[i]):
calibr_data[CALIBR_CHANNELS[i]] = calibr_string_list[i]
else:
raise CP210xEepromOperationError('Product string has the wrong format.')
return calibr_data
def set_calibr_data(self, data):
self.dev.open()
product_string = data[CALIBR_CHANNELS[0]] + ' ' + data[CALIBR_CHANNELS[1]] + ' ' + data[CALIBR_CHANNELS[2]] + ' ' + data[CALIBR_CHANNELS[3]]
#print "New product string value: \"%s\"" % product_string
try:
self.dev.set_product_string(product_string)
print "Calibration data written to cp210x EEPROM."
finally:
self.dev.close()
#!/usr/bin/python
import sys
import rr
import time
class CCSR:
def __init__(self, bus, base_addr, reg_map=None):
self.base_addr = base_addr;
self.bus = bus;
self.reg_map = reg_map
def wr_reg(self, addr, val):
#print(" wr:%.8X reg:%.8X")%(val,(self.base_addr+addr))
self.bus.iwrite(0, self.base_addr + addr, 4, val)
def rd_reg(self, addr):
reg = self.bus.iread(0, self.base_addr + addr, 4)
#print(" reg:%.8X value:%.8X")%((self.base_addr+addr), reg)
return reg
def wr_bit(self, addr, bit, value):
reg = self.rd_reg(addr)
if(0==value):
reg &= ~(1<<bit)
else:
reg |= (1<<bit)
self.wr_reg(addr, reg)
def rd_bit(self, addr, bit):
if(self.rd_reg(addr) & (1<<bit)):
return 1
else:
return 0
#--------------------------------------------
# Get register's field value
def get_field(self, reg, field):
if(reg in self.reg_map[1]): # test if register exist in register map
if(field in self.reg_map[1][reg][2]): # test if field exist in register
reg_addr = self.reg_map[1][reg][0]
field_mask = self.reg_map[1][reg][2][field][2]
field_offset = self.reg_map[1][reg][2][field][0]
reg_val = self.rd_reg(reg_addr)
reg_val = (field_mask & (reg_val >> field_offset))
return reg_val
else:
raise CSRDeviceOperationError(self.base_addr, self.reg_map, 'Requested field (%s) doesn\'t exist.'%field)
else:
raise CSRDeviceOperationError(self.base_addr, self.reg_map, 'Requested register (%s) doesn\'t exist.'%reg)
# Set register's field value
def set_field(self, reg, field, value):
if(reg in self.reg_map[1]): # test if register exist in register map
if(field in self.reg_map[1][reg][2]): # test if field exist in register
reg_addr = self.reg_map[1][reg][0]
field_mask = self.reg_map[1][reg][2][field][2]
field_offset = self.reg_map[1][reg][2][field][0]
reg_val = self.rd_reg(reg_addr)
reg_val &= ~(field_mask << field_offset)
reg_val |= ((field_mask & value) << field_offset)
self.wr_reg(reg_addr, reg_val)
return reg_val
else:
raise CSRDeviceOperationError(self.base_addr, self.reg_map, 'Requested field (%s) doesn\'t exist.'%field)
else:
raise CSRDeviceOperationError(self.base_addr, self.reg_map, 'Requested register (%s) doesn\'t exist.'%reg)
# Set register value
def set_reg(self, reg, value):
if(reg in self.reg_map[1]): # test if register exist in register map
self.wr_reg(self.reg_map[1][reg][0], value)
else:
raise CSRDeviceOperationError(self.base_addr, self.reg_map, 'Requested register (%s) doesn\'t exist.'%reg)
# Get register value
def get_reg(self, reg):
if(reg in self.reg_map[1]): # test if register exist in register map
return self.rd_reg(self.reg_map[1][reg][0])
else:
raise CSRDeviceOperationError(self.base_addr, self.reg_map, 'Requested register (%s) doesn\'t exist.'%reg)
# Print all register map
def print_reg_map(self):
print "\n%s:" % (self.reg_map[0])
print "--------------------------------------------------"
# loop over registers and sort them by address offset
for reg in sorted(self.reg_map[1].iteritems(), key=lambda (k,v): v[0]):
value = self.get_reg(reg[0])
print " * %-50s:0x%08X (%d)" % (reg[1][1],value, value)
# loop over fields and sort them by position
for field in sorted(reg[1][2].iteritems(), key=lambda (k,v): v[0]):
value = self.get_field(reg[0], field[0])
print " - %-48s:0x%X (%d)" % (field[1][1],value, value)
if(len(reg[1][2]) != 0):
print ''
#!/usr/bin/python
import sys
import rr
import time
import onewire
class CDS18B20:
# ROM commands
ROM_SEARCH = 0xF0
ROM_READ = 0x33
ROM_MATCH = 0x55
ROM_SKIP = 0xCC
ROM_ALARM_SEARCH = 0xEC
# DS18B20 fonctions commands
CONVERT_TEMP = 0x44
WRITE_SCRATCHPAD = 0x4E
READ_SCRATCHPAD = 0xBE
COPY_SCRATCHPAD = 0x48
RECALL_EEPROM = 0xB8
READ_POWER_SUPPLY = 0xB4
# Thermometer resolution configuration
RES = {'9-bit':0x0, '10-bit':0x1, '11-bit':0x2, '12-bit':0x3}
def __init__(self, onewire, port):
self.onewire = onewire
self.port = port
def read_serial_number(self):
#print('[DS18B20] Reading serial number')
if(1 != self.onewire.reset(self.port)):
print('[DS18B20] No presence pulse detected')
return -1
else:
#print('[DS18B20] Write ROM command %.2X') % self.ROM_READ
err = self.onewire.write_byte(self.port, self.ROM_READ)
if(err != 0):
print('[DS18B20] Write error')
return -1
family_code = self.onewire.read_byte(self.port)
serial_number = 0
for i in range(6):
serial_number |= self.onewire.read_byte(self.port) << (i*8)
crc = self.onewire.read_byte(self.port)
#print('[DS18B20] Family code : %.2X') % family_code
#print('[DS18B20] Serial number: %.12X') % serial_number
#print('[DS18B20] CRC : %.2X') % crc
return ((crc<<56) | (serial_number<<8) | family_code)
def access(self, serial_number):
#print('[DS18B20] Accessing device')
if(1 != self.onewire.reset(self.port)):
print('[DS18B20] No presence pulse detected')
return -1
else:
#print('[DS18B20] Write ROM command %.2X') % self.ROM_MATCH
err = self.onewire.write_byte(self.port, self.ROM_MATCH)
#print serial_number
block = []
for i in range(8):
block.append(serial_number & 0xFF)
serial_number >>= 8
#print block
self.onewire.write_block(self.port, block)
return 0
def read_temp(self, serial_number):
#print('[DS18B20] Reading temperature')
err = self.access(serial_number)
#print('[DS18B20] Write function command %.2X') % self.CONVERT_TEMP
err = self.onewire.write_byte(self.port, self.CONVERT_TEMP)
time.sleep(0.8)
err = self.access(serial_number)
#print('[DS18B20] Write function command %.2X') % self.READ_SCRATCHPAD
err = self.onewire.write_byte(self.port, self.READ_SCRATCHPAD)
data = self.onewire.read_block(self.port, 9)
#for i in range(9):
# print('Scratchpad data[%1d]: %.2X') % (i, data[i])
temp = (data[1] << 8) | (data[0])
if(temp & 0x1000):
temp = -0x10000 + temp
temp = temp/16.0
return temp
# Set temperature thresholds
# Configure thermometer resolution
#!/usr/bin/python
import sys
import rr
import time
import i2c
class Eeprom24AA64OperationError(Exception):
def __init__(self, addr, msg):
self.msg = msg
self.addr = addr
def __str__(self):
return ("EEPROM 24AA64 [I2C address:0x%02X]: %s" %(self.addr, self.msg))
class C24AA64:
PAGE_SIZE = 32 # in bytes
PAGE_BOUNDARY_MASK = 0xFFFF - (PAGE_SIZE - 1)
def __init__(self, i2c, i2c_addr):
self.i2c = i2c
self.i2c_addr = i2c_addr
def wr_data(self, mem_addr, data):
if len(data) > 32:
print "Maximum sequence write size is 32 byte!"
return -1;
self.i2c.start(self.i2c_addr, True)
self.i2c.write((mem_addr >> 8), False)
self.i2c.write((mem_addr & 0xFF), False)
#print('24AA64:write: data lenght=%d')%(len(data))
for i in range(len(data)-1):
#print('24AA64:write: i=%d')%(i)
self.i2c.write(data[i],False)
if len(data) > 1:
i += 1
else:
i = 0
#print('24AA64:write:last i=%d')%(i)
self.i2c.write(data[i],True)
return 0;
def rd_data(self, mem_addr, size):
self.i2c.start(self.i2c_addr, True)
self.i2c.write((mem_addr >> 8), False)
self.i2c.write((mem_addr & 0xFF), False)
self.i2c.start(self.i2c_addr, False)
data = []
#print('24AA64:read: data lenght=%d')%(size)
for i in range(size-1):
data.append(self.i2c.read(False))
#print('24AA64:read: i=%d')%(i)
#print('24AA64:read:last i=%d')%(i)
data.append(self.i2c.read(True))
return data;
def wr_byte(self, mem_addr, byte):
try:
self.i2c.start(self.i2c_addr, True)
self.i2c.write((mem_addr >> 8), False)
self.i2c.write((mem_addr & 0xFF), False)
self.i2c.write(byte,True)
except I2CDeviceOperationError as e:
raise Eeprom24AA64OperationError(self.i2c_addr, e)
def rd_byte(self, mem_addr):
try:
self.i2c.start(self.i2c_addr, True)
self.i2c.write((mem_addr >> 8), False)
self.i2c.write((mem_addr & 0xFF), False)
self.i2c.start(self.i2c_addr, False)
return self.i2c.read(True)
except I2CDeviceOperationError as e:
raise Eeprom24AA64OperationError(self.i2c_addr, e)
def wr_page(self, mem_addr, data):
try:
#print '[24AA64] write data lenght=%d' % (len(data))
#print '[24AA64] write addr=%04X' % (mem_addr)
if(len(data) == 0):
raise Eeprom24AA64OperationError(self.i2c_addr, "Nothing to transmit, data size is 0!")
if(len(data) > self.PAGE_SIZE):
raise Eeprom24AA64OperationError(self.i2c_addr, "Maximum write size is %d byte!" % self.PAGE_SIZE)
if((mem_addr | self.PAGE_BOUNDARY_MASK) ^ self.PAGE_BOUNDARY_MASK):
raise Eeprom24AA64OperationError(self.i2c_addr, "Start write address is not aligned to a page boundary!")
self.i2c.start(self.i2c_addr, True)
self.i2c.write((mem_addr >> 8), False)
self.i2c.write((mem_addr & 0xFF), False)
#print '[24AA64] write data lenght=%d' % (len(data))
i = 0
for i in range(len(data)-1):
#print '[24AA64] write i=%d' % (i)
self.i2c.write(data[i],False)
if len(data) > 1:
i += 1
#print '[24AA64] write last i=%d' % (i)
self.i2c.write(data[i],True)
except I2CDeviceOperationError as e:
raise Eeprom24AA64OperationError(self.i2c_addr, e)
def rd_seq(self, mem_addr, size):
try:
self.i2c.start(self.i2c_addr, True)
self.i2c.write((mem_addr >> 8), False)
self.i2c.write((mem_addr & 0xFF), False)
self.i2c.start(self.i2c_addr, False)
data = []
#print '[24AA64] read data lenght=%d' % (size)
i=0
for i in range(size-1):
data.append(self.i2c.read(False))
#print '[24AA64] read i=%d' % (i)
if len(data) > 1:
i += 1
#print '[24AA64] read last i=%d' % (i)
data.append(self.i2c.read(True))
return data
except I2CDeviceOperationError as e:
raise Eeprom24AA64OperationError(self.i2c_addr, e)
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
#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
#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
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
CFLAGS = -I../include -g -Imini_bone -Ispll
#uncomment for extra tests (DAC, output stage INL/DNL)
#CFLAGS += -DPERFORM_LONG_TESTS
OBJS_LIB = fdelay_lib.o fdelay_bus.o rr_io.o i2c_master.o onewire.o mini_bone/minibone_lib.o mini_bone/ptpd_netif.o spec_common.o
all: lib
lib: $(OBJS_LIB)
gcc -shared -o libfinedelay.so $(OBJS_LIB)
testprog: lib fdelay_test.o
gcc -o fdelay_test $(OBJS_LIB) fdelay_test.o -lm
testprog2: lib fdelay_cal.o
gcc -o fdelay_cal $(OBJS_LIB) fdelay_cal.o -lm
testprog3: lib fdelay_pps_demo.o
gcc -o fdelay_pps_demo $(OBJS_LIB) fdelay_pps_demo.o -lm
testprog4: lib fdelay_eeprom.o
gcc -o fdelay_eeprom $(OBJS_LIB) fdelay_eeprom.o -lm
clean:
rm -f libfinedelay.so $(OBJS_LIB)
/*
FmcDelay1ns4Cha (a.k.a. The Fine Delay Card)
User-space driver/library - bus API creation functions
Tomasz Włostowski/BE-CO-HT, 2011
(c) Copyright CERN 2011
Licensed under LGPL 2.1
*/
#include <stdio.h>
#include <stdlib.h>
#include "rr_io.h"
#include "minibone_lib.h"
#include "fdelay_lib.h"
static void my_rr_writel(void *priv, uint32_t data, uint32_t addr)
{
rr_writel(data, addr);
}
static uint32_t my_rr_readl(void *priv, uint32_t addr)
{
uint32_t d = rr_readl(addr);
return d;
}
static void my_mb_writel(void *priv, uint32_t data, uint32_t addr)
{
mbn_writel(priv, data, addr >> 2);
}
static uint32_t my_mb_readl(void *priv, uint32_t addr)
{
uint32_t d = mbn_readl(priv, addr >> 2);
return d;
}
fdelay_device_t *fdelay_create_rawrabbit(int fd, uint32_t base_addr)
{
fdelay_device_t *dev = malloc(sizeof(fdelay_device_t));
rr_bind(fd);
dev->writel = my_rr_writel;
dev->readl = my_rr_readl;
dev->base_addr = base_addr;
return dev;
}
fdelay_device_t *fdelay_create_minibone(char *iface, char *mac_addr, uint32_t base_addr)
{
void *handle;
uint8_t target_mac[6];
fdelay_device_t *dev = malloc(sizeof(fdelay_device_t));
sscanf(mac_addr, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", &target_mac[0], &target_mac[1], &target_mac[2], &target_mac[3], &target_mac[4], &target_mac[5]);
handle = mbn_open(iface, target_mac);
if(handle == NULL)
return NULL;
// dbg("%s: remote @ %s [%02x:%02x:%02x:%02x:%02x:%02x], base 0x%08x\n",__FUNCTION__, iface,
// target_mac[0], target_mac[1], target_mac[2], target_mac[3], target_mac[4], target_mac[5], base_addr);
dev->writel = my_mb_writel;
dev->readl = my_mb_readl;
dev->base_addr = base_addr;
dev->priv_io = handle;
return dev;
}
#include <stdio.h>
#include <stdint.h>
#include "fdelay_lib.h"
#include "fdelay_private.h"
#include "fd_main_regs.h"
#include "onewire.h"
#include "rr_io.h"
typedef struct {
float kp, ki, err, pwm, setpoint, i, bias;
} pi_t;
pi_t pi_state = {15.0, 5.0, 0, 0, 20, 0, 2048};
void pi_update(fdelay_device_t *dev, float temp)
{
fd_decl_private(dev);
pi_state.err = temp - pi_state.setpoint;
pi_state.i += pi_state.err;
pi_state.pwm = pi_state.bias + pi_state.kp * pi_state.err + pi_state.ki * pi_state.i;
dbg("t %.1f err:%.1f DRIVE: %d\n", temp, pi_state.err, (int)pi_state.pwm);
fd_writel(FD_I2CR_DBGOUT_W((int)pi_state.pwm), FD_REG_I2CR);
}
extern int64_t get_tics();
static int64_t last_tics = 0;
#define TEMP_REG_PERIOD 1000000LL
int pi_set_temp(fdelay_device_t *dev, float new_temp)
{
int temp;
float temp_f;
if(get_tics() - last_tics < TEMP_REG_PERIOD)
return 0;
last_tics = get_tics();
if(ds18x_read_temp(dev, &temp) < 0)
return 0;
temp_f = (float)temp / 16.0;
pi_state.setpoint = new_temp;
pi_update(dev, temp_f);
dbg("Temperature: %.1f degC err %.1f\n", temp_f, pi_state.err);
return fabs(pi_state.err) < 0.1 ? 1: 0;
}
void my_writel(void *priv, uint32_t data, uint32_t addr)
{
rr_writel(data, addr);
}
uint32_t my_readl(void *priv, uint32_t addr)
{
uint32_t d = rr_readl(addr);
return d;
}
main()
{
fdelay_device_t *dev = malloc(sizeof(fdelay_device_t));
rr_init(RR_DEVSEL_UNUSED, RR_DEVSEL_UNUSED);
dev->writel = my_writel;
dev->readl = my_readl;
dev->base_addr = 0x80000;
if(fdelay_init(dev) < 0)
return -1;
float t_min = 40.0, t_max = 80.0, t_cur;
t_cur = t_min;
for(;;)
{
if(pi_set_temp(dev, t_cur))
{
fd_decl_private(dev);
calibrate_outputs(dev);
fprintf(stderr, "> %.1f %d %d %d %d\n", t_cur, hw->frr_cur[0],
hw->frr_cur[1], hw->frr_cur[2], hw->frr_cur[3]);
t_cur += 1.0;
if(t_cur > t_max)
break;
}
usleep(10000);
}
}
#include <stdio.h>
#include "fdelay_lib.h"
#include "fdelay_private.h"
#include "rr_io.h"
#include "i2c_master.h"
void my_writel(void *priv, uint32_t data, uint32_t addr)
{
rr_writel(data, addr);
}
uint32_t my_readl(void *priv, uint32_t addr)
{
uint32_t d = rr_readl(addr);
return d;
}
main()
{
fdelay_device_t dev;
struct fine_delay_calibration cal;
rr_init(RR_DEVSEL_UNUSED, RR_DEVSEL_UNUSED);
dev.writel = my_writel;
dev.readl = my_readl;
dev.base_addr = 0x84000;
if(fdelay_init(&dev) < 0)
return -1;
cal.magic = 0xf19ede1a;
cal.zero_offset[0] = 63000;
cal.zero_offset[1] = 63000;
cal.zero_offset[2] = 63000;
cal.zero_offset[3] = 63000;
cal.tdc_zero_offset = 35600;
cal.frr_poly[0] = -165202LL;
cal.frr_poly[1] = -29825595LL;
cal.frr_poly[2] = 3801939743082LL;
cal.tdc_zero_offset = 35600;
cal.atmcr_val = 2 | (1000 << 4);
cal.adsfr_val = 56648;
cal.acam_start_offset = 10000;
printf("Writing EEPROM...");
eeprom_write(&dev, EEPROM_ADDR, 0, &cal, sizeof(struct fine_delay_calibration));
printf(" done.\n");
}
This diff is collapsed.
#include <stdio.h>
#include "fdelay_lib.h"
int spec_fdelay_init(int argc, char *argv[], fdelay_device_t *dev);
main(int argc, char *argv[])
{
fdelay_device_t dev;
fdelay_time_t t_cur, t_start;
if(spec_fdelay_init(argc, argv, &dev) < 0)
return -1;
// Get the current time of the FD core - and program the card to start producing the PPS and 10 MHz one second later */
fdelay_get_time(&dev, &t_cur);
printf("Current Time: %lld:%d\n", t_cur.utc, t_cur.coarse);
t_start.coarse = t_cur.coarse;
t_start.utc = t_cur.utc+1;
t_start.frac = 0;
fdelay_configure_pulse_gen(&dev, 1, 1, t_start, 48000LL, 100000LL, -1); /* Output 1, period = 100 ns, width = 48 ns - a bit asymmetric 10 MHz */
fdelay_configure_pulse_gen(&dev, 2, 1, t_start, 48000LL, 1000000000000LL, -1); /* Output 2: period = 1 second, width = 48 ns - PPS signal */
while(!fdelay_channel_triggered(&dev, 1) || fdelay_channel_triggered(&dev, 2))
usleep(10000); /* wait until both outputs have triggered*/;
return 0;
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
OBJS = minibone_lib.o ptpd_netif.o
all: $(OBJS)
gcc -o m $(OBJS)
\ No newline at end of file
This diff is collapsed.
/* MiniBone library. BUGGY CRAP CODE INTENDED FOR TESTING ONLY! */
#ifndef __MINIBONE_LIB_H
#define __MINIBONE_LIB_H
#include <stdint.h>
void *mbn_open(const char *if_name, uint8_t target_mac[]);
void mbn_writel(void *handle, uint32_t d, uint32_t a);
uint32_t mbn_readl(void *handle, uint32_t a);
void mbn_close(void *handle);
#endif
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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