WIP amplifier calibration
authorDan White <dan@whiteaudio.com>
Wed, 18 Jul 2012 01:36:39 +0000 (20:36 -0500)
committerDan White <dan@whiteaudio.com>
Wed, 18 Jul 2012 01:36:39 +0000 (20:36 -0500)
python-lib/calibrate.py
python-lib/mpsse-test.py

index 2158b53c4c509b5c5a787c2d6e1fe5e0fe265f86..31ac82cc0677c59336161d9c5aa1023e1c0bdc24 100644 (file)
@@ -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])
index dce3e8338d82652741a62e7841cee94993cd0fc2..0ca927796a6c579708882977bc22626fb6fd26c3 100755 (executable)
@@ -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