From b9622b42b62be4d7b1b03cd91fa2f3604b0e4781 Mon Sep 17 00:00:00 2001 From: Dan White Date: Thu, 4 Apr 2013 15:41:18 -0500 Subject: [PATCH] arb0 works!!! --- python-lib/arb.py | 120 +++++++++++++- python-lib/calibrate.py | 254 +++++++++++++++++------------ python-lib/chip01-calibration.yaml | 8 +- python-lib/chip14-arb0-test.pdf | Bin 0 -> 17388 bytes python-lib/devboard.py | 15 +- python-lib/slope-arb.py | 102 ++++++++---- 6 files changed, 349 insertions(+), 150 deletions(-) create mode 100644 python-lib/chip14-arb0-test.pdf diff --git a/python-lib/arb.py b/python-lib/arb.py index d895b28..71b5562 100644 --- a/python-lib/arb.py +++ b/python-lib/arb.py @@ -1,18 +1,24 @@ #!/usr/bin/env python -import IPython from time import sleep +import IPython +from pylab import * + import devboard as dev dev.init_devboard(1) # requires devboard be already initialized -from calibrate import calibrate as cal +#import calibrate as cal +import calibrate +cal = calibrate.calibrate -#do_shell = True -do_shell = False +# ?are we already under an IPython shell? +in_ipython = IPython.core.interactiveshell.InteractiveShell.initialized() +# ?be interactive afterwards? +do_shell = True chain = dev.chain @@ -21,9 +27,109 @@ mux = dev.mux arb = dev.arb amux = dev.amux -a = arb.h[0] -m = amux.otaB +a0 = arb.h[0] + +vina = dev.dac.vina +vinb = dev.dac.vinb +vcmi = dev.dac.vcmi + +dac = dev.dac +adc = dev.adc + +#print vina() +#print vinb() +#print vcmi() + +#dev.i2c.NCO_CLK() +#dev.i2c.NCO_CLK() +#dev.i2c.NCO_CLK() + + + +############## +# ch2 +if 0: + print '********************' + print 'ch2' + amux.otaB.mode = amux.otaB.CAL_CMP + amux.otaB.fast = 1 + amux.otaB.gain = 15 + amux.selB = 0 + amux.write() + + for i in range(0, 128, 10): + print i + amux.otaB.offset = i + amux.write() + sleep(0.2) + + + +############# +# ch1 +if 0: + print '********************' + print 'ch1' + amux.selA = 1 + amux.write() + + + a0 = arb.h[0] + + a0.cal = 1 + + a0.otaA.se = 0 + a0.otaA.fast = 1 + a0.otaA.gain = 10 + a0.otaA.cint = 1 + + a0.otaB.se = a0.otaA.se + a0.otaB.fast = a0.otaA.fast + a0.otaB.gain = a0.otaA.gain + a0.otaB.cint = a0.otaA.cint + + arb.write() + + a0.otaA.zero = 1 + a0.otaB.zero = 1 + arb.write() + + a0.otaA.zero = 0 + a0.otaB.zero = 0 + arb.write() + + vcm = 1.25 + + + if 0: + for v in arange(vina(), vcm, 50e-3): + print v + vcmi(v) + vina(v) + vinb(v) + sleep(0.1) + + vcmi(vcm) + vina(vcm) + vinb(vcm) + #raw_input('** pause **') + + for vd in (-0.1, 0.0, 0.1): + print vd + vcmi(vcm) + vina(vcm + vd) + vinb(vcm - vd) + + for i in range(0, 128, 10): + print i + a0.otaA.offset = i + a0.otaB.offset = i + arb.write() + sleep(0.1) + vcmi(vcm) + vina(vcm) + vinb(vcm) @@ -32,6 +138,6 @@ m = amux.otaB ############################################################################## # drop into an IPython shell # -if do_shell: +if do_shell and not in_ipython: IPython.embed() diff --git a/python-lib/calibrate.py b/python-lib/calibrate.py index a0ba2a1..84fb306 100644 --- a/python-lib/calibrate.py +++ b/python-lib/calibrate.py @@ -195,6 +195,7 @@ def offset2signed(v, bits): return (v - 2**(bits-1)) >> 2 def mux_a_offset(x, c, verbose=True): + adc.mux(4) #xi = int(x[0]) xi = int(x) mux.otaA.offset = xi @@ -210,6 +211,7 @@ def mux_a_offset(x, c, verbose=True): return array((mv,)) def mux_b_offset(x, c, verbose=True): + adc.mux(5) xi = int(x) mux.otaB.offset = xi mux.write() @@ -332,6 +334,7 @@ def amux_a_offset(x, c, verbose=True): xi = int(x) amux.otaA.offset = xi amux.write() + adc.mux(6) sleep(MUX_CAL_DELAY) adc.read() values = [] @@ -346,6 +349,7 @@ def amux_b_offset(x, c, verbose=True): xi = int(x) amux.otaB.offset = xi amux.write() + adc.mux(7) sleep(MUX_CAL_DELAY) adc.read() values = [] @@ -437,21 +441,18 @@ def arb_offsets(values, converged, mux_offset, verbose=True): -dac.vina(1.25) -dac.vinb(1.25) -dac.vcmi(1.25) +# TODO: commented out, ensure ADC is init'ed in the right places +#adc.reset() +#adc.triggerMode(adc.MODE_IDLE) +#adc.average(16) +#adc.convst_spi(1) -adc.reset() -adc.triggerMode(adc.MODE_IDLE) -adc.average(16) -adc.convst_spi(1) +#adc.channelMode(4, adc.SE) #even channel only +#adc.channelGain(4, 1) +#adc.channelGain(5, 1) -adc.channelMode(4, adc.SE) #even channel only -adc.channelGain(4, 1) -adc.channelGain(5, 1) - -adc.triggerMode(adc.MODE_MANUAL_MANUAL) +#adc.triggerMode(adc.MODE_MANUAL_MANUAL) @@ -476,6 +477,19 @@ def calibrate(name, elements=None, verbose=True): # if name == 'chain': N_CHANNELS = 48 + + #setup adc + adc.reset() + adc.triggerMode(adc.MODE_IDLE) + + adc.average(16) + adc.convst_spi(1) + adc.channelMode(4, adc.SE) #even channel only + adc.channelGain(4, 1) + adc.channelGain(5, 1) + + adc.triggerMode(adc.MODE_MANUAL_MANUAL) + def func(values, converging): return chain_offsets( values, @@ -483,6 +497,11 @@ def calibrate(name, elements=None, verbose=True): (int(mux.otaA.offset), int(mux.otaB.offset)) ) + #setup mux to buffer + mux.otaA.mode = mux.otaA.MUX_BUF + mux.otaB.mode = mux.otaB.MUX_BUF + mux.write() + #setup initial guess, just use the current values x0 = zeros((2, N_CHANNELS), dtype=int) for i in range(N_CHANNELS): @@ -490,17 +509,34 @@ def calibrate(name, elements=None, verbose=True): x0[j,i] = chain.h[i].ota[j].offset offsets, stats = secant_opt(func, x0, limits, elements=elements, verbose=verbose) + # # Main pad buffer + mux # elif name == 'mux': + adc.reset() + adc.triggerMode(adc.MODE_IDLE) + + adc.average(16) + adc.convst_spi(1) + adc.channelMode(4, adc.SE) #even channel only + adc.channelGain(4, 1) + adc.channelGain(5, 1) + adc.mux(4) + + adc.triggerMode(adc.MODE_MANUAL_MANUAL) + #save mux state - old_mode = [mux.ota[i].mode for i in range(2)] + #old_mode = [mux.ota[i].mode for i in range(2)] mux.otaA.mode = mux.otaA.CAL_CMP mux.otaB.mode = mux.otaB.CAL_CMP + mux.otaA.fast = 1 + mux.otaB.fast = 1 + mux.otaA.gain = 15 + mux.otaB.gain = 15 mux.write() - adc.mux(4) + def func(values, converging): outA = mux_a_offset(values[0], converging[0], verbose) @@ -509,7 +545,7 @@ def calibrate(name, elements=None, verbose=True): out[0] = outA out[1] = outB return out - return array([outA, outB]) + #return array([outA, outB]) #setup initial guess, just use the current values x0 = zeros((2,), dtype=int) @@ -520,9 +556,10 @@ def calibrate(name, elements=None, verbose=True): elements=elements, verbose=verbose) #restore mux state - for i,mode in enumerate(old_mode): - mux.ota[i].mode = mode - mux.write() + #for i,mode in enumerate(old_mode): + #mux.ota[i].mode = mode + #mux.write() + # # Secondary arbitrary function, 16 channels # @@ -546,13 +583,22 @@ def calibrate(name, elements=None, verbose=True): # Secondary pad buffer + mux # elif name == 'amux': + adc.reset() + adc.triggerMode(adc.MODE_IDLE) + adc.average(16) + adc.convst_spi(1) + adc.channelMode(6, adc.SE) #even channel only + adc.channelGain(6, 1) + adc.channelGain(7, 1) + adc.mux(6) + adc.triggerMode(adc.MODE_MANUAL_MANUAL) + #save mux state old_mode = [amux.ota[i].mode for i in range(2)] amux.otaA.mode = amux.otaA.CAL_CMP amux.otaB.mode = amux.otaB.CAL_CMP amux.write() - adc.mux(6) def func(values, converging): outA = amux_a_offset(values[0], converging[0], verbose) @@ -587,101 +633,101 @@ def calibrate(name, elements=None, verbose=True): - -while False: - import datetime as dt - if 1: - mux.otaA.mode = mux.otaA.CAL_BUF - mux.otaA.fast = 1 - mux.otaA.gain = 15 - mux.write() - print - print 'Calibrating mux otaA' - adc.mux(4) - resA, tmp = secant_opt( - mux_a_offset, - zeros((1,), dtype=int), - [-128, 127], - ) - muxA_offset = mean([offset2signed(adc.read(), 16) for i in range(1000)]) - print '*** mux.otaA.offset =', muxA_offset, ' @', resA - else: - resA = 53 - muxA_offset = 0.0 - - - if 1: - mux.otaB.mode = mux.otaB.CAL_BUF - mux.otaB.fast = 1 - mux.otaB.gain = 15 - mux.write() - print - print 'Calibrating mux otaB' - adc.mux(5) - #resB = secant_opt(mux_b_offset, 0, [-128, 127]) - resB, tmp = secant_opt( - mux_b_offset, - zeros((1,), dtype=int), - [-128, 127], - ) - muxB_offset = mean([offset2signed(adc.read(), 16) for i in range(1000)]) - print '*** mux.otaB.offset =', muxB_offset, ' @', resB - else: - resB = 59 - muxB_offset = 0.0 +def do_the_deed(): + while True: + import datetime as dt + if 1: + mux.otaA.mode = mux.otaA.CAL_CMP + mux.otaA.fast = 1 + mux.otaA.gain = 15 + mux.write() + print + print 'Calibrating mux otaA' + adc.mux(4) + resA, tmp = secant_opt( + mux_a_offset, + zeros((1,), dtype=int), + [-128, 127], + ) + muxA_offset = mean([offset2signed(adc.read(), 16) for i in range(1000)]) + print '*** mux.otaA.offset =', muxA_offset, ' @', resA + else: + resA = 53 + muxA_offset = 0.0 - if 0: - offset_chain_a = [] - for n in range(48): + if 1: + mux.otaB.mode = mux.otaB.CAL_CMP + mux.otaB.fast = 1 + mux.otaB.gain = 15 + mux.write() print - print 'Calibrating chain %02i A' % n - adc.triggerMode(adc.MODE_IDLE) - adc.mux(4) - adc.triggerMode(adc.MODE_MANUAL_MANUAL) - mux.selA = n - mux.selB = n + print 'Calibrating mux otaB' + adc.mux(5) + #resB = secant_opt(mux_b_offset, 0, [-128, 127]) + resB, tmp = secant_opt( + mux_b_offset, + zeros((1,), dtype=int), + [-128, 127], + ) + muxB_offset = mean([offset2signed(adc.read(), 16) for i in range(1000)]) + print '*** mux.otaB.offset =', muxB_offset, ' @', resB + else: + resB = 59 + muxB_offset = 0.0 + + + if 0: + offset_chain_a = [] + for n in range(48): + print + print 'Calibrating chain %02i A' % n + adc.triggerMode(adc.MODE_IDLE) + adc.mux(4) + adc.triggerMode(adc.MODE_MANUAL_MANUAL) + mux.selA = n + mux.selB = n + mux.otaA.mode = mux.otaA.MUX_BUF + mux.otaB.mode = mux.otaB.MUX_BUF + mux.write() + nos = secant_opt(lambda x: chain_a_offset(x, n, muxA_offset), resA, (-128, 127)) + mean_os = mean([offset2signed(adc.read(), 16) for i in range(1000)]) + print '*** chain.h[%02i].otaA.offset =' % n, mean_os, ' @', nos + chain_outputs(n) + + if 1: mux.otaA.mode = mux.otaA.MUX_BUF mux.otaB.mode = mux.otaB.MUX_BUF mux.write() - nos = secant_opt(lambda x: chain_a_offset(x, n, muxA_offset), resA, (-128, 127)) - mean_os = mean([offset2signed(adc.read(), 16) for i in range(1000)]) - print '*** chain.h[%02i].otaA.offset =' % n, mean_os, ' @', nos - chain_outputs(n) - - if 1: - mux.otaA.mode = mux.otaA.MUX_BUF - mux.otaB.mode = mux.otaB.MUX_BUF - mux.write() - #def secant_opt(func, x0, limits, elements=None, x1scale=0.1, maxiter=50): + #def secant_opt(func, x0, limits, elements=None, x1scale=0.1, maxiter=50): - chain_os, stats = secant_opt( - lambda x,y: chain_offsets(x, y, (muxA_offset, muxB_offset)), - resA*ones((2,N_CHANNELS), dtype=int), - (-128, 127), - verbose=True, - ) + chain_os, stats = secant_opt( + lambda x,y: chain_offsets(x, y, (muxA_offset, muxB_offset)), + resA*ones((2,N_CHANNELS), dtype=int), + (-128, 127), + verbose=True, + ) - print '-'*80 - print 'offsets:', chain_os[:N_CHANNELS] - print 'N-evals:', stats['nevals'][:N_CHANNELS] - print '-'*80 - print + print '-'*80 + print 'offsets:', chain_os[:N_CHANNELS] + print 'N-evals:', stats['nevals'][:N_CHANNELS] + print '-'*80 + print - #back to h[0] for consistency - mux.selA = 0 - mux.selB = 0 - mux.write() + #back to h[0] for consistency + mux.selA = 0 + mux.selB = 0 + mux.write() - fname = '%s.npz' % (dt.datetime.now().strftime('%Y-%m-%d_%H%M%S'), ) - print '*** writing to %s ***' % fname - savez(fname, - muxres=(resA, resB), - muxos=(muxA_offset, muxB_offset), - chaincal=chain_os, - **stats - ) - break + fname = '%s.npz' % (dt.datetime.now().strftime('%Y-%m-%d_%H%M%S'), ) + print '*** writing to %s ***' % fname + savez(fname, + muxres=(resA, resB), + muxos=(muxA_offset, muxB_offset), + chaincal=chain_os, + **stats + ) + break diff --git a/python-lib/chip01-calibration.yaml b/python-lib/chip01-calibration.yaml index a835582..5a15499 100644 --- a/python-lib/chip01-calibration.yaml +++ b/python-lib/chip01-calibration.yaml @@ -2,8 +2,8 @@ amux: csname: chain1_mux otaA: {fast: 0, gain: 0, mode: 2, offset: 0} otaB: {fast: 0, gain: 0, mode: 2, offset: 0} - selA: 48 - selB: 48 + selA: 16 + selB: 16 arb: csname: chain1_conf harmonics: @@ -279,8 +279,8 @@ mux: csname: chain0_mux otaA: {fast: 1, gain: 15, mode: 2, offset: 44} otaB: {fast: 1, gain: 15, mode: 2, offset: 81} - selA: 0 - selB: 0 + selA: 48 + selB: 48 spi0: cs: _idle: [-1, 200] diff --git a/python-lib/chip14-arb0-test.pdf b/python-lib/chip14-arb0-test.pdf new file mode 100644 index 0000000000000000000000000000000000000000..1a40b32df2ddc1f8314e34dac55f8f2e6094cdf8 GIT binary patch literal 17388 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 TapnYuhNDG6yu6B9N}&G-3$Y(e literal 0 HcmV?d00001 diff --git a/python-lib/devboard.py b/python-lib/devboard.py index 8c234f7..176929a 100644 --- a/python-lib/devboard.py +++ b/python-lib/devboard.py @@ -354,18 +354,13 @@ def load_config(name, delay=0): cfg = yaml.load(open(name, 'rb')) _config.update(cfg) + ########################################################################## # Setup FTDI serial ports spi0 = usbio.SPI(**cfg['spi0']) spi1 = usbio.SPI(**cfg['spi1']) i2c = usbio.I2C(**cfg['i2c']) - sleep(delay) - - ########################################################################## - # Analog bias - # (bias generator also uses DAC_1 and DAC_3, - # need to make a wrapper class to do e.g. ibias.buf = 10 uA) - ibias = usbio.AD524x(i2c, **cfg['ibias']) + #sleep(delay) ########################################################################## # Power supplies @@ -396,6 +391,12 @@ def load_config(name, delay=0): #dac.vbias_core(000e-3) #dac.vbias_buf(000e-3) + ########################################################################## + # Analog bias + # (bias generator also uses DAC_1 and DAC_3, + # need to make a wrapper class to do e.g. ibias.buf = 10 uA) + ibias = usbio.AD524x(i2c, **cfg['ibias']) + ########################################################################## # ADC # (TODO: see 'ADC testing stuff' section below) diff --git a/python-lib/slope-arb.py b/python-lib/slope-arb.py index 75d4448..63e654f 100644 --- a/python-lib/slope-arb.py +++ b/python-lib/slope-arb.py @@ -1,3 +1,16 @@ + + + + +#vina = dev.dac.vina +#vinb = dev.dac.vinb +#vcmi = dev.dac.vcmi + +#arb = dev.arb +#a0 = arb.h[0] + + + while True: vcm = 1.25 @@ -13,44 +26,75 @@ while True: vd = [] tint = [] - for d in arange(-800e-3, 800e-3+1e-3, 10e-3): - print d*1e3 - vd.append(d) + #for i in range(80,130,10): + if 1: + #print '****' + #print '* offset=', i + + #a0.otaA.offset = i + #a0.otaB.offset = i - ti = 0.5 - #for ti in (0.4, 0.2, 0.1, 0.05, 0.025): - while True: - a0.otaA.zero=1; arb.write(); a0.otaA.zero=0; arb.write() - dev.adc.read() - v0 = dev.adc.read() * (2.5 / 2**16) + #a0.otaA.cint = 1 + #a0.otaB.cint = 1 - vina(vcm + d) - vinb(vcm - d) - sleep(ti) - vina(vcm) - vinb(vcm) + #a0.otaA.fast = 1 + #a0.otaB.fast = 1 - dev.adc.read() - v1 = dev.adc.read() * (2.5 / 2**16) + #a0.otaA.gain = 15 + #a0.otaB.gain = 15 + #arb.write() - vo = v1 - v0 + #d = -2.5 + ti = 1.0 + timax = 4.1 + #while d >= -2.5 and d <= 2.5: + for d in arange(-2500e-3, 2500e-3+1e-3, 10e-3): + print d*1e3 + vd.append(d) - print ti, vo - if abs(vo) < 1.1: - break + #for ti in (0.4, 0.2, 0.1, 0.05, 0.025): + while True: + a0.otaA.zero=1; arb.write(); a0.otaA.zero=0; arb.write() + dev.adc.read() + v0 = dev.adc.read() * (2.5 / 2**16) - ti *= 0.5 + vina(vcm + d) + vinb(vcm - d) + sleep(ti) + vina(vcm) + vinb(vcm) - tint.append(ti) - vout.append(vo) - - #sleep(0.1) + dev.adc.read() + v1 = dev.adc.read() * (2.5 / 2**16) + + + vo = v1 - v0 + + print ti, vo + + tiold = ti + if abs(vo) < 0.5: + ti *= 2.0 + elif abs(vo) > 1.1: + ti *= 0.5 + else: + break + + if ti > timax: + ti = tiold + break + + #ti *= 0.5 + + tint.append(ti) + vout.append(vo) + + #sleep(0.1) break -out0 = array(out0) -out1 = array(out1) +vout = array(vout) vd = array(vd) tint = array(tint) @@ -61,11 +105,13 @@ plot(vd, vout, 'o') subplot(223) plot(vd, tint, 'o') -ylim([0, 0.6]) +ylim([0, 1.2*tint.max()]) subplot(222) plot(vd, vout/tint, 'o') +suptitle('Vout*tint vs. vd\nChip #14, arb0') + -- 2.25.1