speed up adc and dac routines (>2x !)
authorDan White <dan@whiteaudio.com>
Fri, 13 Jul 2012 02:53:16 +0000 (21:53 -0500)
committerDan White <dan@whiteaudio.com>
Fri, 13 Jul 2012 02:53:16 +0000 (21:53 -0500)
python-lib/usbio.py

index e1e82a7d3f95186608bcc8ea83ac0850c884fc12..9257b936899ca78e5b6fcde1499548a80b120c34 100644 (file)
@@ -75,8 +75,9 @@ def truth(v):
 def int2str(value, width):
     if (width % 8) != 0:
         raise Exception, 'width must be multiple of 8'
-    v = intbv(value, max=2**width)
-    b = [v[i:i-8] for i in range(width, 0, -8)]
+    #v = intbv(value, max=2**width)
+    #b = [v[i:i-8] for i in range(width, 0, -8)]
+    b = [((value >> i)&0xff) for i in range(width-8, -8, -8)]
     return ''.join(map(chr, b))
 
 def str2hex(x):
@@ -390,7 +391,8 @@ class SPI(object):
             if ret < 0:
                 raise Exception, self.ftdi.get_error_string(self.context)
             r += s
-        self.ftdi.usb_purge_rx_buffer(self.context)
+        #NOTE: including ftdi.SEND_IMMEDIATE commands make this redundant
+        #self.ftdi.usb_purge_rx_buffer(self.context)
         return r
 
     def set_freq(self, freq):
@@ -1117,11 +1119,12 @@ class DAC8568(object):
     def __init__(self, spibus, cs='dac'):
         self.bus = spibus
         self.cs = 'dac'
-        self._word = intbv(0)[self.CTL_WIDTH:]
+        self._word = 0 #intbv(0)[self.CTL_WIDTH:]
         self._chpos = [0 for i in range(8)]
 
     def __str__(self):
-        return ''.join(map(chr, self.bytes()))
+        #return ''.join(map(chr, self.bytes()))
+        return int2str(self.word, self.CTL_WIDTH)
 
     @property
     def word(self):
@@ -1136,7 +1139,8 @@ class DAC8568(object):
     def LDAC(self, bitfield):
         self._clear()
         self._control(0x6)
-        self._word[8:0] = intbv(bitfield, max=2**8)
+        #self._word[8:0] = intbv(bitfield, max=2**8)
+        self._word += (bitfield << 0) #intbv(bitfield, max=2**8)
         self.send()
 
     def swreset(self):
@@ -1155,20 +1159,23 @@ class DAC8568(object):
     def power(self, mode, bitfield):
         self._clear()
         self._control(0x4)
-        self._word[10:8] = intbv(mode, max=2**2)
-        self._word[8:0] = intbv(bitfield, max=2**8)
+        #self._word[10:8] = intbv(mode, max=2**2)
+        self._word += (mode << 8) #intbv(mode, max=2**2)
+        #self._word[8:0] = intbv(bitfield, max=2**8)
+        self._word += (bitfield << 0) #intbv(bitfield, max=2**8)
         self.send()
 
     def reference(self, mode):
         self._clear()
-        self._word = intbv(mode, max=2**32)
+        self._word = mode #intbv(mode, max=2**32)
         self.send()
 
     def bytes(self):
         """Return the control data as a byte sequence in MSB..LSB order."""
-        w = self.word
-        b = [w[i:i-8] for i in range(self.CTL_WIDTH, 0, -8)]
-        return tuple(b)
+        #w = intbv(self.word)
+        #b = [w[i:i-8] for i in range(self.CTL_WIDTH, 0, -8)]
+        b = map(ord, str(self))
+        return b
 
     def send(self):
         self.bus.exchange(str(self), 'dac')
@@ -1177,21 +1184,26 @@ class DAC8568(object):
     # internal functions to help construct a command
     #
     def _clear(self):
-        self._word = intbv(0)[32:]
+        #self._word = intbv(0)[32:]
+        self._word = 0
 
     def _control(self, value):
-        self._word[28:24] = intbv(value, max=2**4)
+        #self._word[28:24] = value #intbv(value, max=2**4)
+        self._word += (value << 24) #intbv(value, max=2**4)
 
     def _address(self, value):
         #other values are no-op addresses
         if (value <= 7) or (value == 15):
-            self._word[24:20] = intbv(value, max=2**4)
+            #self._word[24:20] = value #intbv(value, max=2**4)
+            self._word += (value << 20) #intbv(value, max=2**4)
 
     def _data(self, value):
-        self._word[20:20-self.DAC_WIDTH] = intbv(value, max=2**self.DAC_WIDTH)
+        #self._word[20:20-self.DAC_WIDTH] = value #intbv(value, max=2**self.DAC_WIDTH)
+        self._word += (value << (20-self.DAC_WIDTH)) #intbv(value, max=2**self.DAC_WIDTH)
 
     def _feature(self, value):
-        self._word[4:0] = intbv(value, max=2**4)
+        #self._word[4:0] = value #intbv(value, max=2**4)
+        self._word += (value << 0)#intbv(value, max=2**4)
         
 
 class ADS8201(object):
@@ -1227,8 +1239,8 @@ class ADS8201(object):
 
     def setRegister(self, address, value):
         w = intbv(0x8000)[16:]
-        w[14:10] = intbv(address, max=2**4)
-        w[8:] = intbv(value, max=2**8)
+        w[14:10] = address #intbv(address, max=2**4)
+        w[8:] = value #intbv(value, max=2**8)
         #self.bus.SetCS('adc')
         #self.bus.Start()
         self.bus.write(int2str(w, 16), 'adc')
@@ -1382,10 +1394,11 @@ class ADS8201(object):
         """Read ODR value, meaning of result depends on Mode and FIFO
         settings.  Last 4 LSB are averaging bits."""
         # TODO: also optionally read 4 TAG bits
-        w = intbv(0x0000)[16:]
+        #w = intbv(0x0000)[16:]
         #self.bus.SetCS('adc')
         #self.bus.Start()
-        rval = self.bus.exchange(int2str(w, 16), 'adc')
+        #rval = self.bus.exchange(int2str(w, 16), 'adc')
+        rval = self.bus.exchange('\x00\x00', 'adc')
         #self.bus.Stop()
         i = 8 * (len(rval)-1)
         r = 0