From 13e9cf87b5cbbaffc948237aaa25192bb428d493 Mon Sep 17 00:00:00 2001 From: Dan White Date: Wed, 25 Apr 2012 14:48:19 -0500 Subject: [PATCH] Testing chain0 conf and mux SPI shift registers --- python-lib/mpsse-test.py | 146 +++++++++++++++++++++++++++++++++------ python-lib/usbio.py | 35 ++++++++-- 2 files changed, 156 insertions(+), 25 deletions(-) mode change 100644 => 100755 python-lib/mpsse-test.py diff --git a/python-lib/mpsse-test.py b/python-lib/mpsse-test.py old mode 100644 new mode 100755 index f62ed24..c1502d9 --- a/python-lib/mpsse-test.py +++ b/python-lib/mpsse-test.py @@ -10,6 +10,17 @@ import mpsse import usbio from usbio import int2str +import IPython +import numpy as np + +def bytes2str(self, c): + r = c + if not isinstance(c, str): + if isinstance(c, (tuple, list)): + r = r''.join(map(chr, c)) + else: + raise TypeError, 'Cannot convert type %s to raw string.' % type(c) + return r class AtoiSPI0(mpsse.MPSSE): @@ -22,26 +33,53 @@ class AtoiSPI0(mpsse.MPSSE): def SetCS(self, name): """Setup the chip-select pins for a given 'name'.""" if name == 'flash': - self.context.pidle = self.context.pstop = 0x08 - self.context.pstart = 0x00 + self.context.pidle = self.context.pstop = 0xc8 + self.context.pstart = 0xc0 elif name == 'dac': - self.context.pidle = self.context.pstop = 0x08 - self.context.pstart = 0x18 + self.context.pidle = self.context.pstop = 0xc8 + self.context.pstart = 0xd8 elif name == 'adc': - self.context.pidle = self.context.pstop = 0x08 - self.context.pstart = 0x28 + self.context.pidle = self.context.pstop = 0xc8 + self.context.pstart = 0xe8 elif name == 'convst': - self.context.pidle = self.context.pstop = 0x08 - self.context.pstart = 0x38 + self.context.pidle = self.context.pstop = 0xc8 + self.context.pstart = 0xf8 else: raise Exception, 'Unknown CS name: %s' % name + +class AtoiSPI1(mpsse.MPSSE): + def __init__(self, freq): + super(AtoiSPI1, self).__init__() + self.Open(0x0403, 0x6011, mpsse.SPI0, int(freq), + interface=mpsse.IFACE_B) + self.SetCS('chain0_conf') + + def SetCS(self, name): + """Setup the chip-select pins for a given 'name'.""" + if name == 'chain0_conf': + self.context.pidle = self.context.pstop = 0xf8 + self.context.pstart = 0xf0 + elif name == 'chain0_mux': + self.context.pidle = self.context.pstop = 0xf8 + self.context.pstart = 0xe8 + elif name == 'chain1_conf': + self.context.pidle = self.context.pstop = 0xf8 + self.context.pstart = 0xd0 + elif name == 'chain1_mux': + self.context.pidle = self.context.pstop = 0xf8 + self.context.pstart = 0xb8 + else: + raise Exception, 'Unknown CS name: %s' % name + + + class AtoiI2C(mpsse.MPSSE): def __init__(self, freq): super(AtoiI2C, self).__init__() self.Open(0x0403, 0x6011, mpsse.I2C, int(freq), - interface=mpsse.IFACE_B) + interface=mpsse.IFACE_A) def _tostring(self, c): r = c @@ -79,14 +117,31 @@ class AtoiI2C(mpsse.MPSSE): return r +# +# Atoi UART / rs232 is on IFACE_D +# + + + class DigiReg(usbio.AD524x): + """ + Wrapper for digital potentiometers which control power supply voltages. + Allows setting desired voltage instead of pot position. + + These power supplies have a regulator output of: + Vout = Vref * (1 + (Ra + Rpot)/Rb) + It is sufficient then to specify the end voltages at pos=0 and pos=255 as + the output is linear with pot position. + """ def __init__(self, i2cbus, addr, va=[0.0,1.0], vb=[0.0, 1.0]): super(DigiReg, self).__init__(i2cbus, addr) + # calibration voltages, measure actual hardware self.va_min = min(va) self.va_max = max(va) self.vb_min = min(vb) self.vb_max = max(vb) + # POR pot position self.posA = 128 self.posB = 128 @@ -115,6 +170,14 @@ class DigiReg(usbio.AD524x): vb = property(_vb_getter, _vb_setter) def alias(self, source, dest): + """ + Make a property named by string dest which is an alias for actual + property string source. The valid sources are 'va' and 'vb'. + + > self.alias('va', 'vfoo') + > self.vfoo = 1.2 + > self.va = 1.2 #same effect as above + """ if source == 'va': setattr(DigiReg, dest, property(lambda s: s.va, lambda s,v: s._va_setter(v))) @@ -138,17 +201,15 @@ def dacval(value): return int2str(v, 32) -def w(v): - spi.Start() - spi.Write(v) - spi.Stop() - -spi = AtoiSPI0(100e3) -#spi.SetLoopback(0) - +spi0 = AtoiSPI0(100e3) i2c = AtoiI2C(10e3) +def w(v): + spi0.Start() + spi0.Write(v) + spi0.Stop() + ibias = usbio.AD524x(i2c, 0) @@ -184,7 +245,7 @@ if 0: # if 0: #turn on internal reference always - spi.SetCS('dac') + spi0.SetCS('dac') int_ref_always_on = intbv(0)[32:] int_ref_always_on[27] = 1 @@ -207,7 +268,7 @@ if 0: # ADC testing # if 0: - adc = usbio.ADS8201(spi) + adc = usbio.ADS8201(spi0) adc.setRegister(adc.TRIGGER_SCR, 0x02) rv = adc.getRegister(adc.TRIGGER_SCR) print 'receivd:', b(rv, 16) @@ -239,6 +300,49 @@ def psdefaults(): v430.dvdd = 2.5 -psdefaults() -psdefaults() +#psdefaults() + + + + +def mkcfg(n): + return ''.join(map(chr, np.random.randint(0, 256, n))) + +def cfg2hexstr(x): + return ''.join(map(lambda h: '%02x' % ord(h), x)) + + +# +# chain0 config registers +# +spi1 = AtoiSPI1(100e3) +chain = usbio.Chain(spi1, 'chain0_conf', length=48) +mux = usbio.Mux(spi1, 'chain0_mux') + +#calibration mode for all channels +for h in chain.h: + h.cal = 1 + for ota in h.ota: + ota.se = 0 + ota.cint = 1 + ota.zero = 0 + ota.fast = 1 + ota.gain = 8 + ota.offset = 0 + +cfg = ''.join(map(chr, chain.bytes)) + +spi1.SetCS('chain0_conf') +out = spi1.Exchange(cfg) +print +print ''.join(map(lambda x: '%02x' % ord(x), cfg)) +print +print ''.join(map(lambda x: '%02x' % ord(x), out)) + +out = spi1.Exchange(cfg) +print +print ''.join(map(lambda x: '%02x' % ord(x), out)) + +IPython.embed() + diff --git a/python-lib/usbio.py b/python-lib/usbio.py index b7eeb40..b1e425d 100644 --- a/python-lib/usbio.py +++ b/python-lib/usbio.py @@ -194,14 +194,14 @@ class OTA(object): v = intbv(v, max=2**self.OFFSET_WIDTH).signed() ret = intbv(v, min=-2**(self.OFFSET_WIDTH-1), - max=2**((self.OFFSET_WIDTH-1)-1)) + max=2**((self.OFFSET_WIDTH-1))) return ret @offset.setter def offset(self, value): v = intbv(value, min=-2**(self.OFFSET_WIDTH-1), - max=2**((self.OFFSET_WIDTH-1)-1)) + max=2**((self.OFFSET_WIDTH-1))) #convert to offset binary b = self.OFFSET_SHIFT a = b + self.OFFSET_WIDTH @@ -275,11 +275,16 @@ class Harmonic(object): class Chain(object): - def __init__(self, length=48): + def __init__(self, spibus, csname, length=48): + self.bus = spibus + self.csname = csname self.length = length h = [Harmonic() for i in range(self.length)] self.h = tuple(h) + def __str__(self): + return ''.join(map(chr, self.bytes)) + @property def bytes(self): """Return the control data as a byte sequence in MSB..LSB order.""" @@ -289,6 +294,14 @@ class Chain(object): data.extend(h.bytes) return tuple(data) + def write(self): + self.bus.SetCS(self.csname) + self.bus.Start() + s = str(self) + out = self.bus.Exchange(s) + self.bus.Stop() + return out + class Mux(object): MUX_WIDTH = 48 @@ -305,7 +318,9 @@ class Mux(object): CAL_CMP = 2 CAL_BUF = 3 - def __init__(self): + def __init__(self, spibus, csname): + self.bus = spibus + self.csname = csname self._word = intbv(0)[self.MUX_WIDTH:] self._selA = intbv(48, max=2**self.SEL_WIDTH) #select CMI self._selB = intbv(48, max=2**self.SEL_WIDTH) #select CMI @@ -315,6 +330,9 @@ class Mux(object): self.otaB.mode = self.MUX_BUF self.ota = (self.otaA, self.otaB) + def __str__(self): + return ''.join(map(chr, self.bytes)) + @property def selA(self): return self._selA @@ -352,6 +370,15 @@ class Mux(object): b = [w[i:i-8] for i in range(self.MUX_WIDTH, 0, -8)] return tuple(b) + def write(self): + self.bus.SetCS(self.csname) + self.bus.Start() + s = str(self) + out = self.bus.Exchange(s) + self.bus.Stop() + return out + + class AD524x(object): ADDR_BASE = intbv(0b0101100, max=2**7) -- 2.25.1