Commit 6412605b authored by Theodor-Adrian Stana's avatar Theodor-Adrian Stana

sw: Implemented TTL pulse test

parent 5af5ba24
......@@ -8,7 +8,7 @@ all:
mkdir -p pts-conv-ttl-rs485/lib
cp -r shell/ pts-conv-ttl-rs485/
mv pts-conv-ttl-rs485/shell/program pts-conv-ttl-rs485/boot
wget -P pts-conv-ttl-rs485/boot http://www.ohwr.org/attachments/download/3639/pts.bit
wget -P pts-conv-ttl-rs485/boot http://www.ohwr.org/attachments/download/3640/pts.bit
cp python/pts.py pts-conv-ttl-rs485
cp python/jpts.py pts-conv-ttl-rs485
cp python/vv_pts.py pts-conv-ttl-rs485/lib/
......@@ -20,7 +20,10 @@ all:
sed -i "s/ELMASLOT = 4/ELMASLOT = $(ELMASLOT)/" pts-conv-ttl-rs485/lib/ptsdefine.py
cp python/leds.py pts-conv-ttl-rs485/tests/
cp python/ttl_pulse_switch.py pts-conv-ttl-rs485/tests/
ln -s tests/leds.py pts-conv-ttl-rs485/test01.py
ln -s tests/ttl_pulse_switch.py pts-conv-ttl-rs485/test02.py
clean:
rm -rf pts-conv-ttl-rs485
......
......@@ -83,7 +83,7 @@ def main(bus,tname,inf,log):
break
if inp.find("no") != -1 or inp.find("NO") != -1:
msg = "ERROR: Front Panel LEDs or Schmitt trigger IC5"
msg = "ERROR: Front Panel LEDs or Schmitt trigger ICxxx"
pel.set(msg)
break
......@@ -99,7 +99,7 @@ def main(bus,tname,inf,log):
break
if inp.find("no") != -1 or inp.find("NO") != -1:
msg = "ERROR: Status LEDs or transceiver IC1"
msg = "ERROR: Status LEDs or transceiver ICxxx"
pel.set(msg)
break
......
......@@ -166,15 +166,17 @@ if __name__ == '__main__':
print "---Turn on ELMA!!"
#men_on()
print "FPGA BITSTREAM......"
# print "Loading FPGA bitstream..."
# subprocess.call("cd boot; ./program; cd ..", shell=True, stdout=fnull, stderr=fnull)
# time.sleep(1)
print "Loading FPGA bitstream..."
subprocess.call("cd boot; ./program; cd ..", shell=True, stdout=fnull, stderr=fnull)
time.sleep(1)
# Run JPTS in another shell script; JPTS will handle running each of the test scripts
cmd = "xterm -e ./jpts.py -s %s %s" % (sn1, sn2)
#cmd = "xterm -e ./jpts.py -s %s %s" % (sn1, sn2)
#print "Running tests :%s\n" % (cmd)
#subprocess.call(cmd, shell=True, stdout=fnull, stderr=fnull)
cmd = "./jpts.py -s %s %s" % (sn1, sn2)
print "Running tests :%s\n" % (cmd)
subprocess.call(cmd, shell=True, stdout=fnull, stderr=fnull)
subprocess.call(cmd, shell=True, stdout=sys.stderr, stderr=sys.stderr)
# # After JPTS has finished, download release bitstream to EEPROM chip if none of the tests has failed
# print "Loading CONV-TTL-RS485 release bitstream\n"
......
......@@ -54,9 +54,8 @@ CSR = 0x004
CSR_FRONT_LED_EN_OFS = 0
CSR_REAR_LED_EN_OFS = 1
CSR_STAT_LED_EN_OFS = 2
CSR_TTL_EN_OFS = 0
CSR_BLO_EN_OFS = 1
CSR_BLO_LED_OFS = 2
CSR_TTL_EN_OFS = 3
CSR_REAR_EN_OFS = 4
CSR_RST_UNLOCK_OFS = 14
CSR_RST_OFS = 15
......
##_______________________________________________________________________________________________
##
## CONV-TTL-RS485 PTS
##
## CERN,BE/CO-HT
##_______________________________________________________________________________________________
##
##-----------------------------------------------------------------------------------------------
##
## CONV-TTL-RS485 TTL pulse repetition test
##
##-----------------------------------------------------------------------------------------------
##
## Description This module implements the TTL pulse repetition test. It tests TTL input Schmitt
## triggers IC6 (TTL) and IC11(INV-TTL), along with bus buffers IC2, IC3 and enable
## NAND gate IC10.
##
## There are ten TTL pulse channels this test checks. Six (CH1-6) are TTL
## channels and four (CH6-10) are INV-TTL channels, but the FPGA firmware sends
## TTL pulses on all channels, since the PCB circuits for TTL and INV-TTL channels
## are the same.
##
## Counters are implemented in the firmware to count the number of pulses sent and
## received on a channel. There are two counters per channel, one for input and
## one for output; the counters increment on the rising edge of a pulse signal. The
## current value of each counter can be read via a special Wishbone-mapped slave,
## accessible at base address 0xC00. Below is the full address map for the TTL
## pulse counters:
##
## WB addr Counter
## 0xC00 TTL_CH1_OUT
## 0xC04 TTL_CH1_IN
## 0xC08 TTL_CH2_OUT
## 0xC0C TTL_CH2_IN
## 0xC10 TTL_CH3_OUT
## 0xC14 TTL_CH3_IN
## 0xC18 TTL_CH4_OUT
## 0xC1C TTL_CH4_IN
## 0xC20 TTL_CH5_OUT
## 0xC24 TTL_CH5_IN
## 0xC28 TTL_CH6_OUT
## 0xC2C TTL_CH6_IN
## 0xC30 TTL_CH7_OUT
## 0xC34 TTL_CH7_IN
## 0xC38 TTL_CH8_OUT
## 0xC3C TTL_CH8_IN
## 0xC40 TTL_CH9_OUT
## 0xC44 TTL_CH9_IN
## 0xC48 TTL_CH10_OUT
## 0xC4C TTL_CH10_IN
##
## At hardware level, the channels are daisy-chained, CH1 output to CH2 input,
## CH2 output to CH3 input and so forth, until the last channel, CH10, which is
## connected back to the CH1 input. CH1 generates pulses twice a second which
## get sent from one channel to the other in the daisy chain.
##
## This module contains a pulse counter class which implements methods to decode
## channel pulse counter numbers into their respective address. In the main
## function of the module, a pulse counter object is created and pulses are
## generated from CH10 for 1 second. These pulses are replicated through the
## daisy chain and the counters are updated on each pulse. At the end of the
## test, at least two pulses should be replicated through the daisy chain. The test
## program waits for 1s, stops pulse generation on CH10 and reads the pulse
## counter values. If the number of pulses received on ALL channels matches
## the expected number of pulse, the test passes, otherwise the circuit that
## might be the fault is indicated.
##
## After the TTL lines are tested, the switch lines are read for correct values.
## The switches should in this purpose be set in their default position:
##
## SW1 SW2
## ON | | | | | | | | |o|
## OFF |o|o|o|o| |o|o|o| |
## 1 2 3 4 1 2 3 4
##
## The test checks these lines and since an ON switch connects the FPGA input to
## GND, the above switch setup should yield the value 0xFF. If this value gets
## read back from the switches, the switch test is successful.
##
## Authors Theodor-Adrian Stana (t.stana@cern.ch)
## Website http://www.ohwr.org/projects/conv-ttl-rs485
## Date 31/10/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
sys.path.append("../lib/")
import time
import os, errno, re, struct
import os.path
import traceback
# Import common modules
from ctypes import *
from ptsexcept import *
from vv_pts import *
from ptsdefine 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 wr_out_cnt(self, chan, val):
return self.wr_reg((chan-1)*8, val)
def wr_in_cnt(self, chan, val):
return self.wr_reg((chan-1)*8 + 4, val)
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 : TTL pulse repetition, buffers ICxxx, ICxxx, Schmitt trigger
inputs ICxxx, ICxxx, NAND gate ICxxx
uses : pts.bit and ttl_pulse_switch.py
"""
pel = PTS_ERROR_LOGGER(inf, log)
try:
# Initialize a pulse counter object
pc = CPulseCounter(bus, PULSE_CNT_BASE)
# Clear pulse counters for the TTL channels
for i in range(1, 11):
pc.wr_out_cnt(i, 0)
pc.wr_in_cnt(i, 0)
# Enable pulse generation
val = bus.vv_read(CSR)
val |= (1 << CSR_TTL_EN_OFS)
bus.vv_write(CSR, val)
# wait one second, then disable pulse generation
time.sleep(1)
val &= ~(1 << CSR_TTL_EN_OFS)
bus.vv_write(CSR, val)
# Read the channel registers
ic_arr = []
oc_arr = []
for i in range(1,11):
ic_arr.append(pc.rd_in_cnt(i))
oc_arr.append(pc.rd_out_cnt(i))
# First, check for all-zeroes in counters, indicating enable NAND gate failure
if all(ic == 0 for ic in ic_arr):
msg = "ERROR: No pulses received, check enable NAND gate ICxxx"
pel.set(msg)
# Then, check if the number of pulses sent on the previous channel has
# been received correctly on the current channel
for i in range(0,10):
if (ic_arr[i] != 0) and (ic_arr[i] == oc_arr[i-1]):
msg = "CH%d received %d pulses and sent %d pulses - good\n" % (i+1, ic_arr[i], oc_arr[i])
inf.write(msg)
else:
msg = "ERROR: CH%d received %d pulses and sent %d pulses" % (i+1, ic_arr[i], oc_arr[i])
pel.set(msg)
# Switches test
switches = (bus.vv_read(CSR) & 0xff0000) >> 16
if (switches != 0x80):
msg = "ERROR: Switches readout (0x%x) different from expected (0x80)" % switches
pel.set(msg)
else:
msg = "Switches readout as expected: 0x%x\n" % switches
inf.write(msg)
inf.write("\n")
# 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)
......@@ -155,16 +155,16 @@ class SKT(object):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((ELMAIP, 23))
s.recv(1000)
s.recv(256)
s.send("admin\r\n")
s.recv(1000)
s.recv(256)
s.send(ELMAPWD + "\r\n")
s.recv(1000)
s.recv(256)
self.handle = s
# get crate firmware version, to apply proper address in readreg/writereg
self.handle.send("version\r\n")
ver = self.handle.recv(1000)
ver = self.handle.recv(256)
pos = ver.find("Software version")
if (pos == -1):
print("Unexpected response from \"version\" command, exiting...")
......@@ -185,13 +185,12 @@ class SKT(object):
cm = "writereg %d %d %x\r\n" % (self.lun,rn,value)
#print "vv_write:Debug:cm:%s\n" % (cm)
self.handle.send(cm)
orig = self.handle.recv(1000)
except Exception as e:
msg = "vv_write: No reply from register at address 0x%03x " % (byte_offset)
print msg+orig
raise BusException(msg)
return self.handle.recv(1000).find("Done")
return self.handle.recv(256).find("Done")
def vv_read(self, byte_offset):
""" Read from the application FPGA via ELMA telnet
......@@ -206,7 +205,7 @@ class SKT(object):
cm = "readreg %d %d\r\n" % (self.lun,rn)
#print "vv_read:Debug:cm:%s\n" % (cm)
self.handle.send(cm)
orig = self.handle.recv(1000)
orig = self.handle.recv(256)
rp = orig
rp = rp.split(" ")[3]
rp = rp.split("\n")[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