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):
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
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
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)))
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)
#
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
# 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)
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()
+
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
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."""
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
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
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
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)