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