HV Control Board Functional Test Definition
February 10, 2005
N. Kitamura
Notes
The total time should be about 5 minutes.
The tests must be very simple for the operator to perform.
The HV generator’s specs are valid only after one hour of warm up.
Check the test fixture’s power supply voltage and regulation.
The scope of the tests—can’t do long term stability, line rejection, etc.
Focus on detecting clear defects in two categories:
Correct power up and power down
Voltage accuracy and short term stability (<1 min)
Plus,
HV ID readout
The following description is in the order of execution of the tests.
Initialization
HVID readout
Read HV using iceboot N times every T seconds.
N = 10, T = 1.
Pass/Fail
Pass iff all N readouts are the same non-zero value.
Explanation
The iceboot command performs several reads and performs CRC check. Thus, just one reading may seem to be necessary, but last year’s production data show that the readout may not be consistent.
HV Ramp Up
Ramp up the DAC at D counts per second from 0 up to Dmax=4095. Read the ADC and the voltmeter at each DAC increment.
Pass/Fail
ADC_pass iff ADC readout vs DAC is okay.
HV_pass iff voltmeter readout vs DAC is okay.
Explanation
The Generator SCD:
“Linearity definition”
Stability defined as voltage deviations not exceeding 0.2% of the set point over 8 hours and the rate of deviations not exceeding 0.2% per hour (3.2.2.4.2)
Programming linearity better than 0.5% over 20% to100% of max output (3.2.2.5.3)
Monitor linearity better than 0.5% over 20% to 100% of max output (3.2.2.6.3)
Monitor accuracy better than +/-1% from 20%-100% of max output (3.2.2.6.4)
The generator’s spec is convoluted with
DAC linearity
ADC linearity
Voltage reference accuracy and stability
Voltage divider accuracy
Volt meter accuracy
HV Ramp Down
Ramp down the DAC at D counts per second from 4095 down to 0. Read the ADC and the voltmeter at each DAC decrement.
HV Enable
Repeated Readout
HV Disable
Shutdown
Data
#------functions that analyze data for pass/fail ------
def check_initialize(self):
"""
Place holder for now. Just say pass
"""
return 'pass'
def check_finish(self):
"""
Pass iff the HV output at this timing is less than the specified value.
"""
if abs(float(self.Vfinish)*HV_DIVIDER_SCALE) < HV_FINISH_VOLT:
return 'pass'
else:
return 'fail'
def check_hvid(self):
"""
Pass iff all members of ID are the same non-zero value.
There is no CRC check here because IceBoot takes care of it.
"""
ID = self.HVIDreads
#IceBoot (hal) bug fix
from FixHVID import reverse_id, remove_CRC
for i in range(len(ID)):
ID[i] = remove_CRC(reverse_id(ID[i]))
assert len(ID) >= 2
last = ID[0]
if int(last, 16)==0:
return 'fail'
for i in range(1, len(ID)):
if ID[i]>last:
return 'fail'
else:
last = ID[i]
self.HVIDreads = ID
return 'pass'
def _linearity_test(self, D, A, H):
"""
This function is called by check_HVrampUP and check_HVrampDN.
Let D, A, and H be DAC, ADC, and HV, respectively.
Dv, Av, Hv = Scaled voltage units (nom range 0 - 2.047.5V)
Model:
Av = a1 * Dv + b1
Hv = a2 * Dv + b2
Pass <=> |a1 - 1| < ADC_LINEARITY_ERROR
|a2 - 1| < HV_LINEARITY_ERROR
i.e., both slopes must be within (specified value x 100)% of unity.
"""
assert len(D)==len(A)
assert len(D)==len(H)
# See scale(...) in calc.py
Dv = scale(DAC_VOLT_PER_BIT, D)
Av = scale(ADC_VOLT_PER_BIT, foreach(A, float))
Hv = scale(HV_DIVIDER_SCALE, foreach(H, float))
a1, b1 = lsm(Dv, Av) # Least-square fit
a2, b2 = lsm(Dv, Hv)
ans = ''
if abs(a1 - 1)< ADC_LINEARITY_ERROR:
ans = ans + 'ADC_pass'
else:
ans = ans + 'ADC_fail'
ans = ans + '+'
if abs(a2 - 1)< HV_LINEARITY_ERROR:
ans = ans + 'HV_pass'
else:
ans = ans + 'HV_fail'
return ans, a1, b1, a2, b2
def check_HVrampUP(self):
ans, a1, b1, a2, b2 = self._linearity_test(self.DAC, self.ADCup, self.Voltup)
self.HVrampUP_fit = [a1, b1, a2, b2]
return ans
def check_HVrampDN(self):
self.ADCdn.reverse()
self.Voltdn.reverse()
ans, a1, b1, a2, b2 = self._linearity_test(self.DAC, self.ADCdn, self.Voltdn)
self.ADCdn.reverse()
self.Voltdn.reverse()
self.HVrampDN_fit = [a1, b1, a2, b2]
return ans
def check_HVenable(self):
"""
Pass <=>
ADC and HV values reach within EN_READY_LEVEL*100 % of target value
in EN_READY_TIME seconds after HV is enabled, where the target value
is one set by DAC_ENABLE_VAL.
"""
Vadc0 = DAC_ENABLE_VAL*DAC_VOLT_PER_BIT #Target ADC voltage
Vhv0 = Vadc0/HV_DIVIDER_SCALE #Target volt meter voltage
i = int(EN_READY_TIME / ENABLE_WAIT_SEC) #When to check / dwell time per pt
if i >= ENABLE_TIMES:
i = ENABLE_TIMES-1
Vadc1 = float(self.ADCen[i])*ADC_VOLT_PER_BIT
Vhv1 = float(self.Volten[i])
ans = ''
if abs((Vadc1 - Vadc0)/Vadc0) < EN_READY_LEVEL:
ans = ans + 'ADC_pass'
else:
ans = ans + 'ADC_fail'
ans = ans + '+'
if abs((Vhv1 - Vhv0)/Vhv0) < EN_READY_LEVEL:
ans = ans + 'HV_pass'
else:
ans = ans + 'HV_fail'
return ans
def check_HVdisable(self):
"""
Pass <=>
ADC and HV values fall by DIS_READY_LEVEL*100 % from the initial value
in DIS_READY_TIME seconds after HV is disabled, where the initial value
is one set by DAC_ENABLE_VAL.
"""
Vadc0 = DAC_ENABLE_VAL*DAC_VOLT_PER_BIT
Vhv0 = Vadc0/HV_DIVIDER_SCALE
i = int(DIS_READY_TIME / DISABLE_WAIT_SEC)
if i >= DISABLE_TIMES:
i = DISABLE_TIMES-1
Vadc1 = float(self.ADCdis[i])*ADC_VOLT_PER_BIT
Vhv1 = float(self.Voltdis[i])
ans = ''
if abs((Vadc1 - Vadc0)/Vadc0) > DIS_READY_LEVEL:
ans = ans + 'ADC_pass'
else:
ans = ans + 'ADC_fail'
ans = ans + '+'
if abs((Vhv1 - Vhv0)/Vhv0) > DIS_READY_LEVEL:
ans = ans + 'HV_pass'
else:
ans = ans + 'HV_fail'
return ans
def check_HVreads(self):
"""
Statistical test after repeated readout at a fixed DAC value.
(m1, s1) = ADC value mean, stdev
(m2, s2) = HV value mean, stdev
m10 = DAC_ENABLE_VAL (fixed DAC value)
m20 = DAC_ENABLE_VAL * DAC_VOLT_PER_BIT
Pass <=>
|(m1 - m10)/m10| < ADC_MEAN_ERROR
|(m2 - m20)/m20| < HV_MEAN_ERROR
s1 < ADC_STD_ERROR
s2 < HV_STD_ERROR
"""
(m1, s1) = meansdev(foreach(self.ADCrep, float))
# tmp = scale(HV_DIVIDER_SCALE, foreach(self.Vrep, float))
(m2, s2) = meansdev(scale(HV_DIVIDER_SCALE, foreach(self.Vrep, float)))
# (m2, s2) = meansdev(foreach(self.Vrep, float))
m10 = DAC_ENABLE_VAL
m20 = DAC_ENABLE_VAL * DAC_VOLT_PER_BIT
ans = ''
if abs((m1 - m10)/m10)< ADC_MEAN_ERROR and s1 < ADC_STD_ERROR:
ans = ans + 'ADC_pass'
else:
ans = ans + 'ADC_fail'
ans = ans + '+'
if abs((m2 - m20)/m20)< HV_MEAN_ERROR and s2 < HV_STD_ERROR:
ans = ans + 'HV_pass'
else:
ans = ans + 'HV_fail'
self.HVreads_stat = [m1, s1, m2, s2]
return ans
def judge(self):
"""
Fail, if there is at least one test that failed.
Pass, otherwise.
"""
how_many = 0
failed = []
for (k,v) in self.test_result.items():
tmp = v.count('fail')
if tmp > 0:
failed.append(k)
how_many += tmp
return how_many, failed
Appendixhvglobals2.pyw (check if this is the same as prod version)
"""
Global Definitions for test_manager2.py
hv_globals2.py
For PY4 IceCube production of the HV Control Boards
"""
## Program identification
TESTSCRIPT_NAME = 'IceCube HV Control Test Script 3/16/2005'
## File locations
DATA_PATH = 'c:\\hvtest2005\\data' # Test data directory
PARAM_PATH = 'c:\\hvtest2005\\param' # Test run log files
## Names of the test run log files ("parameter files")
OPERATOR_LIST_FILE = 'OPERATOR_LIST.LST' # Catalog of operators
DATAFILE_LIST_FILE = 'DATAFILE_LIST.LST' # Catalog of data files
RUNID_LIST_FILE = 'RUNID_LIST.LST' # Catalog of RunIDs
SERIAL_NUM_LIST_FILE = 'SERIAL_NUM_LIST.LST' # Catalog of all the serial numbers
HV_BRICK_LIST_FILE = 'HV_BRICK_LIST.LST' # Catalog of all the brick numbers
## The following symbols are used in the Run IDs and the data file names
## <RunID> ::=
## <prefix>PARAM_SEP<product name>PARAM_SEP<serial number>PARAM_SEP<run number>
## <DataFileName> ::= <RunID>.DATA_EXT
RUNID_PREFIX = 'PES' # Pensar Electronic Solutions
PRODUCT_NAME = 'HVC' # High-voltage control board
PARAM_SEP = '_' # Separator used in Run ID and Data Filename
DATA_EXT = 'DAT' # Data filename extention
## Needed for legacy reason
DEFAULT_IP_ADDRESS = '172.16.35.111'
## COM port assignment
## A Lantronix terminal server was used in CY2004 production. For CY2005, both the Fluke45
## meter and the DOMMB are connected to the PC USB ports using a COM-to-USB adapter for each
## port.
# Note the port number starts from zero.
# e.g., COM1==>0, COM2==>1, etc.
DEFAULT_DOMMB_PORT = 3 # Port number for DOMMB (COM4)
DEFAULT_DVMM_PORT = 2 # Port number for the Fluke 45 DMM (COM3)
## ADC and DAC scaling factor
DAC_VOLT_PER_BIT = 0.5 # DAC LT1257 scale
ADC_VOLT_PER_BIT = 0.5 # ADC LT1286 scale
## DVM readout scaling factor
## The HV output is connected to a 130MOhm standard load which also acts as a voltage divider.
## (HV volt) = HV_DIVIDER_SCALE * (DVM readout)
HV_DIVIDER_SCALE = 978.44 # Resistor ratio measured with Fluke45 (3/11/2005)
# The ratio is consistent with calibration measurements
# made with a standard HV supply (Model HV-1547,
# Power Designs Pacific, Inc.)
## hvid test parameters
REPEAT_HVID_TIMES = 10 # Read this many times consistently to pass
## Linearity test parameters
RAMP_WAIT_SEC = 0.1 # Wait before next DAC value. Defines ramping speed.
ADC_LINEARITY_ERROR = 0.025 # The slope shall not deviate from unity by more than this
HV_LINEARITY_ERROR = 0.025 # (ditto)
## HV enable test parameters
ENABLE_TIMES = 30 # Number of data points (how many times to read ADC)
ENABLE_WAIT_SEC = 0.1 # Time between reads
DAC_ENABLE_VAL = 3000 # This defines V0
EN_READY_TIME = 5 # = t1 Check ready after this many seconds
EN_READY_LEVEL = 0.1 # = K Pass iff |(V(t1) - V0)/V0| < K
## HV disable test parameters
DISABLE_TIMES = 30 # Number of data points (how many times to read ADC)
DISABLE_WAIT_SEC = 0.1 # Time between reads
DIS_READY_TIME = 5 # = t2 Check if ready after this many seconds
DIS_READY_LEVEL = 0.9 # = L Pass iff |(V0 - V(t2))/V0| < L
## Repeated HV read test parameters
REPEAT_READ_TIMES = 100 # Read this many times for statistics
REPEAT_WAIT_SEC = 0.5 # Wait this long between reads
ADC_MEAN_ERROR = 0.03 # ADC mean must stay within this fraction of target (DAC)
HV_MEAN_ERROR = 0.03 # HV mean must stay within this fraction of target
ADC_STD_ERROR = 1 # The StdDev of ADC reads must be less than this
HV_STD_ERROR = 1 # The StdDev of HV reads must be less than this
## Shut down test parameters
FINISH_WAIT_SEC = 15 # = t3 Wait period before telling operator that test is done
HV_FINISH_VOLT = 30 # HV output (V) must be less than this t3 after IceBoot
# disable command