paranoid timing for CS, SK setting
authorDan White <dan@whiteaudio.com>
Tue, 17 Jul 2012 02:33:32 +0000 (21:33 -0500)
committerDan White <dan@whiteaudio.com>
Tue, 17 Jul 2012 02:33:32 +0000 (21:33 -0500)
Move the SK pin to the data-start state before asserting the CS pins.  Then we
are sure to not wiggle SK when CS is (being) asserted and (maybe) violate some
timing-related error.

python-lib/usbio.py

index 47bf3ab7d411a9174267e246df5ee14b7f812830..0308b55e481f91d9b6605133eb7a1ad84e198c10 100644 (file)
@@ -487,17 +487,34 @@ class SPI(object):
         sham, mask = self.cs['_mask']
         mode, pins = self.cs[device]
 
-        p = self._pinstate & ~mask
-        p += pins & mask
+        # set SK before asserting CS to not violate timing
+        if True:
+            # first, ensure SK starts in the correct state
+            p = self._pinstate
+            if mode in (0, 1):
+                p |= 0x01
+            elif mode in (2, 3):
+                p &= 0xfe
+            cmd = chr(self.ftdi.SET_BITS_LOW) + chr(p) + chr(self._pindir)
+
+            p &= ~mask
+            p += pins & mask
+            self._pinstate = p
+            cmd += chr(self.ftdi.SET_BITS_LOW) + chr(p) + chr(self._pindir)
+        # old behavior: set CS and SK in same command
+        else:
+            p = self._pinstate & ~mask
+            p += pins & mask
 
-        # ensure SK starts in the correct state
-        if mode in (0, 1):
-            p |= 0x01
-        elif mode in (2, 3):
-            p &= 0xfe
+            # ensure SK starts in the correct state
+            if mode in (0, 1):
+                p |= 0x01
+            elif mode in (2, 3):
+                p &= 0xfe
+
+            self._pinstate = p
+            cmd = chr(self.ftdi.SET_BITS_LOW) + chr(p) + chr(self._pindir)
 
-        self._pinstate = p
-        cmd = chr(self.ftdi.SET_BITS_LOW) + chr(p) + chr(self._pindir)
         return cmd
 
     def _mk_cs_cmd_cache(self):