Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
##_______________________________________________________________________________________________
##
## CONV-TTL-RS485 PTS
##
## CERN,BE/CO-HT
##_______________________________________________________________________________________________
##
##-----------------------------------------------------------------------------------------------
##
## CONV-TTL-RS485 LEDs test
##
##-----------------------------------------------------------------------------------------------
##
## Description Testing the rear-transition module interface of the CONV-TTL-RS485 front module
## board. This is done in conjunction with gateware implemented on the
## CONV-TTL-RS485 FPGA.
##
## The gateware implements pulse repeaters which are controlled by this script to
## send pulses back to inputs. Externally to the RTM, there should be two boards
## containing differential multiplexers, and these are controlled by the FPGA HDL
## through this script such that each channel sends pulses back to itself, in the
## sequence O1->I, O2->I, O3->I.
##
## In short, what this script does is to turn on pulse repetition, sleep for a
## predefined amount of time, and then check that the same number of pulses that has
## been sent at the channel output are received at its input. The checking is done by
## reading the input and output channel pulse counters, implemented in the FPGA HDL.
## Checking is done with input and output terminations ON and OFF (one run of the same
## test sequence for both).
##
## Authors Julian Lewis (Julian.Lewis@cern.ch)
## Theodor-Adrian Stana (t.stana@cern.ch)
## Website http://www.ohwr.org/projects/pts
## Date 11/11/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 system modules
import sys
sys.path.append("pyts")
import time
# Import common modules
from ptsexcept import *
from vv_pts import *
from ptsdefine import *
#--------------------------------------------------------------------------------------------------
# Pulse counter class
#--------------------------------------------------------------------------------------------------
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)
#--------------------------------------------------------------------------------------------------
# Test sequences
#--------------------------------------------------------------------------------------------------
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
def mux_sel(bus, sel):
val = bus.vv_read(CSR)
val &= ~(1 << CSR_TESTER_MUX_S0_OFS)
val &= ~(1 << CSR_TESTER_MUX_S1_OFS)
if (sel & 0x1):
val |= (1 << CSR_TESTER_MUX_S0_OFS)
if (sel & 0x2):
val |= (1 << CSR_TESTER_MUX_S1_OFS)
bus.vv_write(CSR, val)
def en_pulse_gen(bus):
val = bus.vv_read(CSR)
val |= (1 << CSR_REAR_EN_OFS)
bus.vv_write(CSR, val)
def dis_pulse_gen(bus):
val = bus.vv_read(CSR)
val &= ~(1 << CSR_REAR_EN_OFS)
bus.vv_write(CSR, val)
def clear_counters(pc):
# Clear pulse counters for the TTL channels
for i in range(11, 17):
pc.wr_out_cnt(i, 0)
pc.wr_in_cnt(i, 0)
def check_counters(pc, inf, pel):
ic_arr = []
oc_arr = []
for i in range(11, 17):
ic_arr.append(pc.rd_in_cnt(i))
oc_arr.append(pc.rd_out_cnt(i))
for i in range(len(ic_arr)):
if (ic_arr[i] == oc_arr[i]):
msg = "Ch%d input counter (%d) matches the output counter (%d) - good\n" % (i+1,
ic_arr[i], oc_arr[i])
inf.write(msg)
else:
msg = "ERROR: Ch%d input counter (%d) does not match output counter (%d)"% (i+1,
ic_arr[i], oc_arr[i])
pel.set(msg)
##-------------------------------------------------------------------------------------------------
## main --
##-------------------------------------------------------------------------------------------------
def main(bus, tname, inf, log):
"""
tests : RS-485 pulse repetition, RS-485 transceivers IC31-IC56,
solid-state switches IC56-IC75, solid-state switches
IC23-IC28, RS-485 transceivers IC16-IC21, Schmitt trigger
inputs IC30, IC45, NAND gate IC8, IC69 Schmitt trigger for
the RTM detection lines
uses : pts.bit and rs485_pulse_rtm.py
"""
pel = PTS_ERROR_LOGGER(inf, log)
try:
# Read RTM lines
rtm = (bus.vv_read(CSR) >> CSR_RTM_OFS) & 0x3f
if (rtm == 0x09):
msg = "RTM detection lines read correctly: 0x%02X" % rtm
inf.write(msg+'\n')
else:
msg = "ERROR: RTM detection lines readout (0x%02X) incorrect - expected 0x09. Check RTM presence or IC69" % rtm
pel.set(msg)
return pel.get()
# Initialize a pulse counter object
pc = CPulseCounter(bus, PULSE_CNT_BASE)
clear_counters(pc)
# Ask the user to make the daisy-chain
print("Connect the LEMO cable as follows:")
print(" - BLU cable to INV-TTL CH A")
print(" - GRN cable to INV-TTL CH B")
print(" - RED cable to INV-TTL CH C")
print(" - YEL cable to INV-TTL CH D")
reply = raw_input("Have the connections been made? (yes/no) ")
while (1):
if "yes" in reply.lower():
break
if "no" in reply.lower():
msg = "ERROR: Control connections to RS485 tester not made"
pel.set(msg)
return pel.get()
else:
reply = raw_input('Please type "yes" or "no" to continue: ')
# Power on the tester card
val = bus.vv_read(CSR)
val |= (1 << CSR_TESTER_VCC_OFS)
bus.vv_write(CSR, val)
#---------------------------
# Test with terminations OFF
#---------------------------
# Read out fail-safe lines -- should now be high, since the MUXes are
# powered but not enabled
val = bus.vv_read(LSR)
val >>= LSR_REARFS_OFS
if (val == 0x3f):
msg = "RS-485 failsafe lines read as expected: 0x%02X\n" % val
inf.write(msg)
else:
msg = "ERROR: Failsafe lines readout (0x%02X) incorrect - expected 0x3F" % val
pel.set(msg)
# Enable multiplexer
print("Enabling multiplexers")
val = bus.vv_read(CSR)
val |= (1 << CSR_TESTER_MUX_EN_OFS)
bus.vv_write(CSR, val)
# Generate pulses from different outputs to inputs
msg = "Testing channel connections (term. OFF): O1 -> I"
inf.write('\n')
inf.write(msg+'\n')
en_pulse_gen(bus)
time.sleep(2)
dis_pulse_gen(bus)
check_counters(pc, inf, pel)
clear_counters(pc)
msg = "Testing channel connections (term. OFF): O2 -> I"
inf.write('\n')
inf.write(msg+'\n')
en_pulse_gen(bus)
time.sleep(2)
dis_pulse_gen(bus)
check_counters(pc, inf, pel)
clear_counters(pc)
msg = "Testing channel connections (term. OFF): O3 -> I"
inf.write('\n')
inf.write(msg+'\n')
en_pulse_gen(bus)
time.sleep(2)
dis_pulse_gen(bus)
check_counters(pc, inf, pel)
clear_counters(pc)
msg = "Testing RS-485 fail-safe on short-circuit case (term. OFF)"
inf.write('\n')
en_pulse_gen(bus)
Theodor-Adrian Stana
committed
val = bus.vv_read(LSR)
val >>= LSR_REARFS_OFS
if (val == 0x3f):
msg = "RS-485 failsafe lines read as expected: 0x%02X\n" % val
inf.write(msg)
else:
msg = "ERROR: Failsafe lines readout (0x%02X) incorrect - expected 0x3F" % val
pel.set(msg)
dis_pulse_gen(bus)
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
# Disable multiplexer
print("Disabling multiplexers")
val = bus.vv_read(CSR)
val &= ~(1 << CSR_TESTER_MUX_EN_OFS)
bus.vv_write(CSR, val)
#--------------------------
# Test with terminations ON
#--------------------------
# Read out fail-safe lines -- should now be high, since the MUXes are
# powered but not enabled
val = bus.vv_read(LSR)
val >>= LSR_REARFS_OFS
if (val == 0x3f):
msg = "RS-485 failsafe lines read as expected: 0x%02X\n" % val
inf.write(msg)
else:
msg = "ERROR: Failsafe lines readout (0x%02X) incorrect - expected 0x3F" % val
pel.set(msg)
inf.write('\n')
msg = "Enabling input and output terminations"
print(msg)
inf.write(msg + '\n')
bus.vv_write(TER, (0x3f << TER_OTERM_OFS) | (0x3f << TER_ITERM_OFS))
time.sleep(2)
# Enable multiplexer
print("Enabling multiplexers")
val = bus.vv_read(CSR)
val |= (1 << CSR_TESTER_MUX_EN_OFS)
bus.vv_write(CSR, val)
# Generate pulses from different outputs to inputs
msg = "Testing channel connections (term. ON): O1 -> I"
print(msg)
mux_sel(bus, 0x0)
inf.write('\n')
inf.write(msg+'\n')
en_pulse_gen(bus)
time.sleep(2)
dis_pulse_gen(bus)
check_counters(pc, inf, pel)
clear_counters(pc)
msg = "Testing channel connections (term. ON): O2 -> I"
print(msg)
mux_sel(bus, 0x1)
inf.write('\n')
inf.write(msg+'\n')
en_pulse_gen(bus)
time.sleep(2)
dis_pulse_gen(bus)
check_counters(pc, inf, pel)
clear_counters(pc)
msg = "Testing channel connections (term. ON): O3 -> I"
print(msg)
mux_sel(bus, 0x2)
inf.write('\n')
inf.write(msg+'\n')
en_pulse_gen(bus)
time.sleep(2)
dis_pulse_gen(bus)
check_counters(pc, inf, pel)
clear_counters(pc)
msg = "Testing RS-485 fail-safe on short-circuit case (term. ON)"
print(msg)
mux_sel(bus, 0x3)
inf.write('\n')
inf.write(msg+'\n')
en_pulse_gen(bus)
val = bus.vv_read(LSR)
val >>= LSR_REARFS_OFS
if (val == 0x3f):
msg = "RS-485 failsafe lines read as expected: 0x%02X\n" % val
inf.write(msg)
else:
msg = "ERROR: Failsafe lines readout (0x%02X) incorrect - expected 0x3F" % val
pel.set(msg)
dis_pulse_gen(bus)
# Disable multiplexer
print("Disabling multiplexers")
val = bus.vv_read(CSR)
val &= ~(1 << CSR_TESTER_MUX_EN_OFS)
bus.vv_write(CSR, val)
return pel.get()
except BusException, e:
raise PtsError("SKT Exception: %s" % e)
except BusWarning, e:
raise PtsError("SKT Warning: %s" % e)
finally:
val = bus.vv_read(CSR)
val &= ~(1 << CSR_TESTER_VCC_OFS)
val &= ~(1 << CSR_TESTER_MUX_EN_OFS)
val &= ~(1 << CSR_TESTER_MUX_S0_OFS)
val &= ~(1 << CSR_TESTER_MUX_S1_OFS)
bus.vv_write(CSR, val)