Commit 405816b6 authored by Theodor-Adrian Stana's avatar Theodor-Adrian Stana

rtm-sw: Added Python test scripts from old PTS repo

parent 1751fa71
##_______________________________________________________________________________________________
##
## CONV-TTL-BLO-RTM PTS
##
## CERN,BE/CO-HT
##_______________________________________________________________________________________________
##
##-----------------------------------------------------------------------------------------------
##
## CONV-TTL-BLO-RTM pulse test
##
##-----------------------------------------------------------------------------------------------
##
## Description This module implements the blocking pulse test of the CONV-TTL-BLO-RTM PTS.
##
## The pulse test uses two RTM board testers which loops back each output to three
## adjacent outputs, as seen below:
##
## O1 I1 I2 I3
## O2 I2 I3 I1
## O3 I3 I1 I2
## O4 I4 I5 I6
## O5 I5 I6 I4
## O6 I6 I4 I5
##
## The firmware inside the driving CONV-TTL-BLO waits for this script to write the
## number of pulses to send on a channel of choice and enable pulse sending. Then,
## through the RTM board tester, a pulse signal is looped back to the inputs as seen
## above. Each time a pulse is output an output pulse counter is incremented, and
## each time a pulse is received on a channel an input pulse counter is incremented.
##
## For the memory map of the pulse counters, see the memory map in the HDL guide.
##
## This script cycles through each of the channels in turn and initiates the sending
## of seven pulses. It then waits one second and starts reading the input pulse
## counters. On each channel, a theoretical number of pulses sent is calculated and
## then the input counter is verified versus this theoretical number of pulses. If
## the input counter matches it, the test passes, otherwise it fails.
##
## Seeing as how on each channel we send seven pulses, a cycle for the first two
## channels would look like this:
## - send 7 pulses on channel 1
## - output counter on channel 1 should show 7
## - input counters on channels 1, 2 and 3 should show 7
## - send 7 pulses on channel 2
## - output counter on channel 2 should show 7
## - input counters on channels 1, 2 and 3 should show 14
##
## Both the input and output pulse counters values are stored to the output .inf file
## and an error is flagged appropriately, should it occur.
##
## Authors Theodor-Adrian Stana (t.stana@cern.ch)
## Website http://www.ohwr.org/projects/pts
## Date 24/01/2014
##-----------------------------------------------------------------------------------------------
##
##------------------------------------------------------------------------------------------------
## GNU LESSER GENERAL PUBLIC LICENSE
## ------------------------------------
## This source file is free software; you can redistribute it and/or modify it under the terms of
## the GNU Lesser General Public License as published by the Free Software Foundation; either
## version 2.1 of the License, or (at your option) any later version.
## This source 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 Lesser General Public License for more details.
## You should have received a copy of the GNU Lesser General Public License along with this
## source; if not, download it from http://www.gnu.org/licenses/lgpl-2.1.html
##-------------------------------------------------------------------------------------------------
##-------------------------------------------------------------------------------------------------
## Import
##-------------------------------------------------------------------------------------------------
# Import system modules
import sys
import time
import os, errno, re, sys, struct
import os.path
import traceback
# Import common modules
from ctypes import *
from ptsexcept import *
from vv_pts import *
from pts_memmap import *
class CPulseCounter:
def __init__(self, bus, base):
self.bus = bus
self.base = base
def wr_reg(self, addr, val):
self.bus.vv_write(self.base + addr,val)
def rd_reg(self, addr):
return self.bus.vv_read(self.base + addr)
def rd_out_cnt(self, chan):
return self.rd_reg((chan-1)*8)
def rd_in_cnt(self, chan):
return self.rd_reg((chan-1)*8 + 4)
##-------------------------------------------------------------------------------------------------
## main --
##-------------------------------------------------------------------------------------------------
def main(bus, tname, inf, log):
"""
tests : Blocking pulse repetition and output connectors
uses : pts_conv_ttl_blo_rtm.bit and blo_pulse.py
"""
pel = PTS_ERROR_LOGGER(inf, log)
inf.write("Pulse counter values:\n")
inf.write("---------------------\n")
try:
# Initialize a pulse counter object
pc = CPulseCounter(bus, PULSE_CNT_BASE)
# Number of pulses to send
nr_pulses = 7
# Init theoretical input count variable and counter for zeroes in ic_arr
ic_sim = 0
zero_cnt = 0
for i in range(1, 7):
# First, set the start index based on the channel where the RTM board
# tester is placed:
# CH1->3: board tester 1
# CH4->6: board tester 2
si = 1
if i >= 4:
si = 4
# End index is always start index + 3, due to RTM board tester looping
# back three channels at a time
ei = si+3
# Clear theoretical input counter array on the fourth channel, since
# this is where the second board tester is
if (i == 4):
ic_sim = 0
zero_cnt = 0
# Compute theoretical number of pulses for the channel based on the number of
# pulses sent
ic_sim += nr_pulses
# Send pulses on the current output channel
val = (1 << CSR_PEN_OFS) | (i << CSR_CHN_OFS) | (nr_pulses << CSR_NP_OFS)
bus.vv_write(CSR, val)
# wait one second, then start reading input and output counter values
time.sleep(1)
# Read the channel registers, blocking channels 1-6 correspond to pulse
# counter channels 1-6
ic_arr = []
oc_arr = []
for j in range(si, ei):
ic_arr.append(pc.rd_in_cnt(j))
oc_arr.append(pc.rd_out_cnt(j))
# Check for all zeroes in input count
if all(j == 0 for j in ic_arr):
zero_cnt += 1
# Compare input count array with theoretical input count
for j in range(3):
if (ic_arr[j] == ic_sim):
msg = "good : O%d = %2d / I%d = %2d\n" % (i, oc_arr[i-si], (si+j)%(ei), ic_arr[j])
inf.write(msg)
else:
msg = "ERROR: O%d = %2d / I%d = %2d - expected %2d" % (i, oc_arr[i-si], (si+j)%(ei), ic_arr[j], ic_sim)
pel.set(msg)
# Check for all zeroes on all three channels in a group
if zero_cnt == 3:
msg = "ERROR: No pulses received on O%d, O%d, O%d. Check RTM board tester and/or front module board blocking power supply." % (i-2, i-1, i)
pel.set(msg)
# Finally, return the number of errors that occured
return pel.get()
except BusException, e:
raise PtsError("SKT Exception: %s" % (e))
except BusWarning, e:
raise PtsError("SKT Warning: %s" % (e))
This diff is collapsed.
##_______________________________________________________________________________________________
##
## CONV-TTL-BLO-RTM PTS
##
## CERN,BE/CO-HT
##_______________________________________________________________________________________________
##
##-----------------------------------------------------------------------------------------------
##
## CONV-TTL-BLO-RTM LEDs test
##
##-----------------------------------------------------------------------------------------------
##
## Description Testing the rear panel LEDs on the CONV-TTL-BLO-RTM.
##
## This test script writes the LDTEN bit in the CSR of the PTS firmware on the
## CONV-TTL-BLO front module driving the RTM. Setting this bit initiates the
## sequencing of the pulse LEDs on the rear panel.
##
## The firmware sequences each LED starting from channel 1 and ending with channel 6
## and the user is asked to confirm all LEDs light up, for the test to pass.
##
## Authors Theodor-Adrian Stana (t.stana@cern.ch)
##
## Website http://www.ohwr.org/projects/pts
## Date 12/04/2013
##-----------------------------------------------------------------------------------------------
##
##------------------------------------------------------------------------------------------------
## GNU LESSER GENERAL PUBLIC LICENSE
## ------------------------------------
## This source file is free software; you can redistribute it and/or modify it under the terms of
## the GNU Lesser General Public License as published by the Free Software Foundation; either
## version 2.1 of the License, or (at your option) any later version.
## This source 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 Lesser General Public License for more details.
## You should have received a copy of the GNU Lesser General Public License along with this
## source; if not, download it from http://www.gnu.org/licenses/lgpl-2.1.html
##-------------------------------------------------------------------------------------------------
##-------------------------------------------------------------------------------------------------
## Import
##-------------------------------------------------------------------------------------------------
# Import system modules
import sys
import time
import os, errno, re, sys, struct
import os.path
import traceback
# Import common modules
from ctypes import *
from ptsexcept import *
from vv_pts import *
from pts_memmap import *
##-------------------------------------------------------------------------------------------------
## main --
##-------------------------------------------------------------------------------------------------
def main(bus,tname,inf,log):
"""
tests : Rear panel LEDs
uses : pts_conv_ttl_blo_rtm.bit and leds.py
"""
pel = PTS_ERROR_LOGGER(inf,log)
try:
# Enable pulse LED sequencing
bus.vv_write(CSR, 1 << CSR_LDTEN_OFS)
# The firmware should blink the LEDs, ask the operator for input
inp = raw_input("--> Are the channel LEDs blinking one by one? yes/no: ")
while True:
if inp.find("yes") != -1 or inp.find("YES") != -1:
break
if inp.find("no") != -1 or inp.find("NO") != -1:
msg = "ERROR: Rear panel LEDs"
pel.set(msg)
break
inp = raw_input("Please type 'yes' or 'no' to continue:")
return pel.get()
except BusException, e:
raise PtsError("SKT Exception: %s" % (e))
except BusWarning, e:
raise PtsError("SKT Warning: %s" % (e))
This diff is collapsed.
#===============================================================================
# CERN (BE-CO-HT)
# PTS memory map
#===============================================================================
# author: Theodor Stana (t.stana@cern.ch)
#
# date of creation: 2014-01-14
#
# version: 1.0
#
# description:
# This module contains register address definitions that are used across the
# various tests. Importing this module inside a test script makes these
# definitions available for use within a bus.vv_write or bus.vv_read method
# (see vv_pts.py for these methods).
#
# dependencies:
# none.
#
# references:
# none.
#
#===============================================================================
# GNU LESSER GENERAL PUBLIC LICENSE
#===============================================================================
# This source file is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the
# Free Software Foundation; either version 2.1 of the License, or (at your
# option) any later version. This source 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 Lesser General Public License for more details. You should have
# received a copy of the GNU Lesser General Public License along with this
# source; if not, download it from http://www.gnu.org/licenses/lgpl-2.1.html
#===============================================================================
# last changes:
# 2014-01-14 Theodor Stana t.stana@cern.ch File created
#===============================================================================
# TODO: -
#===============================================================================
# Registers used across all test programs
BOARD_ID_REG = 0x000
CSR = 0x004
CSR_PEN_OFS = 0
CSR_CHN_OFS = 1
CSR_NP_OFS = 4
CSR_LDTEN_OFS = 7
CSR_RST_OFS = 15
# Pulse counter base address, used in blo_pulse.py
PULSE_CNT_BASE = 0x100
class PtsException(Exception):
pass
class PtsCritical(PtsException):
"""critical error, abort the whole test suite"""
pass
class PtsUser(PtsException):
"""error, user intervention required"""
pass
class PtsWarning(PtsException):
"""warning, a cautionary message should be displayed"""
pass
class PtsInvalid(PtsException):
"""reserved: invalid parameters"""
class PtsNoBatch(PtsInvalid):
"""reserved: a suite was created without batch of tests to run"""
pass
class PtsBadTestNo(PtsInvalid):
"""reserved: a bad test number was given"""
pass
class PtsInfo(PtsException):
"""Information from the test, not an error"""
class PtsError(PtsException):
"""error, continue remaining tests in test suite"""
pass
class PTS_ERROR_LOGGER:
"""Log errors and continue testing without raising an exception"""
def __init__(self, inf, log):
self.inf = inf
self.log = log
self.er_count = 0
def set(self, msg):
self.inf.write(msg + "\n")
self.log.write(msg + "\n")
self.er_count = self.er_count + 1
def get(self):
return self.er_count
if __name__ == '__main__':
pass
##_______________________________________________________________________________________________
##
## CONV-TTL-BLO-RTM PTS
##
## CERN,BE/CO-HT
##_______________________________________________________________________________________________
##
##-----------------------------------------------------------------------------------------------
##
## CONV-TTL-BLO RTM detection lines test
##
##-----------------------------------------------------------------------------------------------
##
## Description This test script checks the RTM detection lines by reading the RTM field in the
## CSR of the PTS firmware downloaded to the CONV-TTL-BLO. It then checks that the
## RTM detection lines match a known board combination, as per the RTM detection
## lines webpage on OHWR:
## www.ohwr.org/projects/conv-ttl-blo/wiki/rtm_board_detection
##
## If they match a combination, this combination is listed in the PTS .inf file for
## the board. Otherwise, an error is flagged and the state of the RTM lines is
## printed in the same file.
##
## Authors Theodor-Adrian Stana (t.stana@cern.ch)
## Website http://www.ohwr.org/projects/pts
## Date 24/01/2014
##-----------------------------------------------------------------------------------------------
##
##------------------------------------------------------------------------------------------------
## GNU LESSER GENERAL PUBLIC LICENSE
## ------------------------------------
## This source file is free software; you can redistribute it and/or modify it under the terms of
## the GNU Lesser General Public License as published by the Free Software Foundation; either
## version 2.1 of the License, or (at your option) any later version.
## This source 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 Lesser General Public License for more details.
## You should have received a copy of the GNU Lesser General Public License along with this
## source; if not, download it from http://www.gnu.org/licenses/lgpl-2.1.html
##-------------------------------------------------------------------------------------------------
##-------------------------------------------------------------------------------------------------
## Import
##-------------------------------------------------------------------------------------------------
# Import system modules
import sys
import time
import os, errno, re, sys, struct
import os.path
import traceback
# Import common modules
from ctypes import *
from ptsexcept import *
from vv_pts import *
from pts_memmap import *
##-------------------------------------------------------------------------------------------------
## main --
##-------------------------------------------------------------------------------------------------
def main(bus, tname, inf, log):
"""
tests : RTM detection lines
uses : pts_conv_ttl_blo_rtm.bit and rtm_det.py
"""
pel = PTS_ERROR_LOGGER(inf, log)
try:
rtmdet = bus.vv_read(CSR) & 0x3f000000
rtmdet >>= 24
rtmp = rtmdet & 0x38
rtmm = rtmdet & 0x07
if (rtmm == 0x01) and (rtmp == 0x00):
msg = "Detected CONV-TTL-RTM with blocking piggyback.\n"
inf.write(msg)
elif (rtmm == 0x01) and (rtmp == 0x01):
msg = "Detected CONV-TTL-RTM with RS-485 piggyback.\n"
inf.write(msg)
elif (not rtmm) and (not rtmp):
msg = "ERROR: RTM detection lines read incorrect or unknown value: 0x%02x." % rtmdet
pel.set(msg)
# Finally, return the number of errors that occured
return pel.get()
except BusException, e:
raise PtsError("SKT Exception: %s" % (e))
except BusWarning, e:
raise PtsError("SKT Warning: %s" % (e))
#! /usr/bin/python
# coding: utf8
# Copyright CERN, 2014
# Author: Julian Lewis <julian.lewis@cern.ch>
# Theodor Stana <t.stana@cern.ch>
# Licence: GPL v2 or later.
# Website: http://www.ohwr.org
import sys
import time
from ctypes import *
import os, errno, re, sys, struct
import os.path
from ptsexcept import *
import socket
from socket import SHUT_RDWR
from pts_memmap import *
class BusException(Exception):
pass
class BusWarning(Exception):
pass
class VME(object):
def __init__(self,lun):
""" The vmeio driver lun (logical unit).
At driver install time, insmod maps lun on to
VME (csr, application window, interrupts).
Lun is set when creating a VME object
"""
self.lib = CDLL('./libvv_pts.so')
int = 0
if type(lun) == type(int):
self.lun = lun
else:
self.lun = int
raise BusWarning("Warning: VME __init__: Bad lun, default to 0")
def vv_init(self):
""" Initialize the library
loads the libvv_pts.so dynamic library
opens vmeio driver for lun 0
prepares the svec bootloader
"""
self.handle = cast(self.lib.vv_init(self.lun), c_void_p)
if self.handle == 0:
raise BusException("Failed vv_init: Can't initialize VME library")
return self.handle
def vv_close(self):
""" Close the driver and free up resources
"""
cc = self.lib.vv_close(self.handle)
self.handle = 0
if cc != 0:
raise BusException("Failed vv_close: Can't close VME library")
return cc
def vv_load(self, bit_stream, id):
""" Load the FPGA
reads the FPGA bitstream image file
initializes the svec bootloader
loads the FPGA image
initializes the loaded VME core for lun 0
"""
cc = self.lib.vv_load(self.handle, bit_stream, id)
if cc == -1:
raise BusException("Failed vv_load: Can't load bit_stream: %s" % (bit_stream))
return cc
def vv_write(self, byte_offset, value):
""" Write to the application FPGA wishbone bus
The byte offset will be aligned to D32
The value is a 32 bit integer
"""
x = c_int(value)
cc = self.lib.vv_write(self.handle, byte_offset, byref(x), 4)
if cc != 0:
raise BusException("Failed vv_write: offset:0x%X value:%d" % (byte_offset, value))
return cc
def vv_write_array(self, byte_offset, buf, size):
""" Write an array of data from the string array buf
size is the number of bytes to write aligned D32
"""
cc = self.lib.vv_write(self.handle, byte_offset, id(buf), size)
if cc != 0:
raise BusException("Failed vv_write_array: offset:0x%X size:%d" % (byte_offset, size))
return cc
def vv_read(self, byte_offset):
""" Read from the application FPGA wishbone bus
The byte offset will be aligned to D32
The value will contain the 32 bit integer read
"""
x = c_int(0)
cc = self.lib.vv_read(self.handle, byte_offset, byref(x), 4)
value = x.value
if cc != 0:
raise BusException("Failed vv_read: offset:0x%X" % (byte_offset))
return value & 0xFFFFFFFF
def vv_read_array(self, byte_offset, buf, size):
""" Read size bytes into the string array buf
The byte_offset and size will be D32 aligned
"""
cc = self.lib.vv_read(self.handle, byte_offset, id(buf), size)
if cc != 0:
raise BusException("Failed vv_read_array: offset:0x%X size:%d" % (byte_offset, size))
return cc
def vv_irqwait(self):
""" Wait for an interrupt
An ISR is installed and reads the interrupt source register from the FPGA application
If no interrupt occurs after one second the return is -1 and errno is ETIME
"""
x = c_int(0)
cc = self.lib.vv_irqwait(self.handle, byref(x))
irq_src = x.value
if cc != 0:
raise BusException("Failed vv_irqwait: No interrupt")
return irq_src
class PCI(object):
def __init__(self,lun):
""" The pciio driver lun (logical unit).
"""
self.lib = CDLL('./libvv_pts.so')
int = 0
if type(lun) == type(int):
self.lun = lun
else:
self.lun = int
raise BusWarning("Warning: PCI __init__: Bad lun, default to 0")
class SKT(object):
def __init__(self,lun,hostname,password):
""" Telnet access over a socket to ELMA I2C bus
"""
int = 4
if type(lun) == type(int):
self.lun = lun
else:
self.lun = int
raise BusWarning("Warning: SKT __init__: Bad lun=(slot), default to 4")
self.base = 0;
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((hostname, 23))
s.recv(1000)
s.send("admin\r\n")
s.recv(1000)
s.send(password + "\r\n")
s.recv(1000)
self.handle = s
def vv_write(self, byte_offset, value):
""" Write to the application FPGA via ELMA telnet
The byte offset will be aligned to D32
The value is a 32 bit integer
"""
try:
cm = "writereg %d %x %x\r\n" % (self.lun,byte_offset,value)
#print "vv_write:Debug:cm:%s\n" % (cm)
self.handle.send(cm)
except Exception, e:
msg = "vv_write: No reply from register: %x" % (byte_offset)
raise BusException(msg)
return self.handle.recv(1000).find("Done")
def vv_read(self, byte_offset):
""" Read from the application FPGA via ELMA telnet
The byte offset will be aligned to D32
The value will contain the 32 bit integer read
"""
try:
cm = "readreg %d %x\r\n" % (self.lun,byte_offset)
#print "vv_read:Debug:cm:%s\n" % (cm)
self.handle.send(cm)
orig = self.handle.recv(1000)
rp = orig
rp = rp.split(" ")[3]
rp = rp.split("\n")[0]
rp = int(rp,16)
except Exception, e:
msg = "vv_read: No reply from register: %x" % (byte_offset)
print msg+orig
raise BusException(msg)
return rp
def vv_load(self):
""" Load the FPGA, its a NO-OP in SKT class
"""
if self.vv_read(BOARD_ID_REG) == 0x54424c4f:
return 1
else:
raise BusException("Failed vv_load: FPGA: Bad board ID")
return 0
def vv_init(self):
""" Init the library, its a NO-OP in SKT class
"""
return self.handle
def vv_close(self):
""" Close the socket
"""
self.handle.shutdown(SHUT_RDWR)
self.handle.close()
self.handle = 0
return 0
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