From: Dan White Date: Wed, 18 Jul 2012 01:36:39 +0000 (-0500) Subject: WIP amplifier calibration X-Git-Tag: calibrations~19 X-Git-Url: http://git.whiteaudio.com/gitweb/?a=commitdiff_plain;h=4cb2850e7a0626b2ddefedbf50ab434294695c50;p=430.git WIP amplifier calibration --- diff --git a/python-lib/calibrate.py b/python-lib/calibrate.py index 2158b53..31ac82c 100644 --- a/python-lib/calibrate.py +++ b/python-lib/calibrate.py @@ -1,6 +1,102 @@ +def bisect(fset, limits=[0.0, 1.0], dgmin=None, up='uk', down='dj'): + """Given a one-input function fset and list of limits, interactively bisect + the range by sending fset(guess) and asking to go (u)p or (d)own for the + next step. Each stepsize is progressively halved and optionally limited to + dgmin if given.""" + xmin = min(limits) + xmax = max(limits) + g = (xmax - xmin) / 2 + xmin + dg = (xmax - xmin) / 4 + last = xmin + + guess = [xmin, xmax] + + quit = False + while quit == False: + print 'sending guess:', g, dg + guess.append(g) + fset(g) + + a = raw_input('q, a, [%s], [%s] ? ' % (up, down)).lower() + if a == 'q': + quit = True + return guess[2:] + + if a in down: + g = g - dg + elif a in up: + g = g + dg + elif a in 'a': + #again, keep same guess, do not modify dg + continue + else: + print 'OOPS, expecting u or d only' + + # limit values + g = min(g, xmax) + g = max(g, xmin) + + dg = dg / 2 + # for ints, step size stops at 1 + if isinstance(xmin, int): + dg = max(dg, 1) + elif dgmin is not None and dg < dgmin: + dg = dgmin + + + + +def offset2signed(v, bits): + return (v - 2**(bits-1)) >> 2 + + +def mux_a_offset(x): + xi = int(round(x)) + mux.otaA.offset = xi + mux.write() + adc.read() + values = [] + for i in range(N_SAMPLES): + values.append(offset2signed(adc.read(), 16)) + sleep(DELAY) + mv = mean(values) + print xi, mv + return mv + +def mux_b_offset(x): + xi = int(round(x)) + mux.otaB.offset = xi + mux.write() + adc.read() + values = [] + for i in range(N_SAMPLES): + values.append(offset2signed(adc.read(), 16)) + sleep(DELAY) + mv = mean(values) + print xi, mv + return mv + +def chain_a_offset(x, n, mux_offset): + xi = int(round(x)) + cn = chain.h[n] + cn.cal = 1 + cn.otaA.se = 1 + cn.otaA.cint = 0 + cn.otaA.offset = xi + chain.write() + sleep(0.5) + adc.read() + values = [] + for i in range(N_SAMPLES): + values.append(offset2signed(adc.read(), 16)) + sleep(DELAY) + mv = mean(values) + print xi, mv + return mv - mux_offset + dac.vina(1.25) dac.vinb(1.25) dac.vcmi(1.25) @@ -10,34 +106,55 @@ adc.triggerMode(adc.MODE_IDLE) adc.channelMode(4, adc.SE) #even channel only adc.channelGain(4, 1) adc.channelGain(5, 1) -adc.mux(4) mux.otaA.mode = mux.otaA.CAL_BUF -mux.otaB.mode = mux.otaB.CAL_CMP +mux.otaA.gain = 15 +mux.otaB.mode = mux.otaB.CAL_BUF +mux.otaB.gain = 15 mux.write() adc.triggerMode(adc.MODE_MANUAL_MANUAL) -def offset2signed(v, bits): - return v - 2**(bits-1) - -def mux_a_offset(x): - mux.otaA.offset = x - mux.write() - for i in range(10): - print offset2signed(adc.read(), 16) - sleep(0.1) +from scipy.optimize import brentq -def mux_b_offset(x): - mux.otaB.offset = x - mux.write() - for i in range(10): - print offset2signed(adc.read(), 16) - sleep(0.1) +N_SAMPLES = 10 +DELAY = 0.01 +print print 'Calibrating mux otaA' -bisect(mux_a_offset, [-128, 127]) +adc.mux(4) +resA = brentq(mux_a_offset, -128, 127, xtol=0.01, disp=True) +print resA +muxA_offset = mean([offset2signed(adc.read(), 16) for i in range(1000)]) +print '*** mux.otaA.offset =', int(round(resA)) + + +if 0: + print + print 'Calibrating mux otaB' + adc.mux(5) + resB = brentq(mux_b_offset, -128, 127, xtol=0.01, disp=True) + print resB + muxB_offset = mean([offset2signed(adc.read(), 16) for i in range(1000)]) + print '*** mux.otaB.offset =', int(round(resB)) + + +offset_chain_a = [] +for n in range(48): + print + print 'Calibrating chain %02i A' % n + adc.mux(4) + mux.selA = n + mux.selB = n + mux.otaA.mode = mux.otaA.MUX_BUF + mux.otaB.mode = mux.otaB.MUX_BUF + mux.write() + nos = brentq(lambda x: chain_a_offset(x, n, muxA_offset), + -128, 127, + xtol=0.01, + disp=True) + mean_os = mean([offset2signed(adc.read(), 16) for i in range(1000)]) + print nos, mean_os + print '*** chain.h[%02i].otaA.offset = %+3i' % (n, int(round(nos))) -print 'Calibrating mux otaB' -bisect(mux_a_offset, [-128, 127]) diff --git a/python-lib/mpsse-test.py b/python-lib/mpsse-test.py index dce3e83..0ca9277 100755 --- a/python-lib/mpsse-test.py +++ b/python-lib/mpsse-test.py @@ -34,50 +34,6 @@ def str2hex(x): return ''.join(map(lambda h: '%02x' % ord(h), x)) -def bisect(fset, limits=[0.0, 1.0], dgmin=None, up='uk', down='dj'): - """Given a one-input function fset and list of limits, interactively bisect - the range by sending fset(guess) and asking to go (u)p or (d)own for the - next step. Each stepsize is progressively halved and optionally limited to - dgmin if given.""" - xmin = min(limits) - xmax = max(limits) - g = (xmax - xmin) / 2 + xmin - dg = (xmax - xmin) / 4 - last = xmin - - guess = [xmin, xmax] - - quit = False - while quit == False: - print 'sending guess:', g, dg - guess.append(g) - fset(g) - - a = raw_input('q, a, [%s], [%s] ? ' % (up, down)).lower() - if a == 'q': - quit = True - return guess[2:] - - if a in down: - g = g - dg - elif a in up: - g = g + dg - elif a in 'a': - #again, keep same guess, do not modify dg - continue - else: - print 'OOPS, expecting u or d only' - - # limit values - g = min(g, xmax) - g = max(g, xmin) - - dg = dg / 2 - # for ints, step size stops at 1 - if isinstance(xmin, int): - dg = max(dg, 1) - elif dgmin is not None and dg < dgmin: - dg = dgmin