Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Added the old, proof of concept code into the FT232R-JTAG.old folder.

  • Loading branch information...
commit b55ccbf8b413532bcb5aeb37723a81b0b62e4b94 1 parent 285502a
@fpgaminer fpgaminer authored
View
94 FT232R-JTAG.old/BitstreamReader.py
@@ -0,0 +1,94 @@
+# Parse a .BIT file generated by Xilinx's bitgen.
+# That is the default file generated during ISE's compilation.
+#
+#
+# FILE FORMAT
+#
+# Consists of an initial 11 bytes of unknown content (???)
+# Then 5 fields of the format:
+# 1 byte key
+# 2 byte, Big Endian Length (EXCEPT: The last field, which has a 4 byte length)
+# data (of length specified above ^)
+#
+# The 5 fields have keys in the sequence a, b, c, d, e
+# The data from the first 4 fields are strings:
+# design name, part name, date, time
+# The last field is the raw bitstream.
+#
+
+
+class BitFileReadError(Exception):
+ _corruptFileMessage = "Unable to parse .bit file; header is malformed. Is it really a Xilinx .bit file?"
+
+ def __init__(self, value=None):
+ self.parameter = BitFileReadError._corruptFileMessage if value is None else value
+ def __str__(self):
+ return repr(self.parameter)
+
+class BitFile:
+ # Read a .bit file and return a BitFile object.
+ @staticmethod
+ def read(filestream):
+ bitfile = BitFile()
+
+ # 11 bytes of unknown data
+ if BitFile._readLength(filestream) != 9:
+ raise BitFileReadError()
+
+ BitFile._readOrDie(filestream, 11)
+
+ bitfile.designname = BitFile._readField(filestream, 'a').rstrip('\0')
+ bitfile.part = BitFile._readField(filestream, 'b').rstrip('\0')
+ bitfile.date = BitFile._readField(filestream, 'c').rstrip('\0')
+ bitfile.time = BitFile._readField(filestream, 'd').rstrip('\0')
+
+ if BitFile._readOrDie(filestream, 1) != 'e':
+ raise BitFileReadError()
+
+ length = BitFile._readLength4(filestream)
+ bitfile.bitstream = BitFile._readOrDie(filestream, length)
+
+ return bitfile
+
+ # Read a 2-byte, unsigned, Big Endian length.
+ @staticmethod
+ def _readLength(filestream):
+ length = BitFile._readOrDie(filestream, 2)
+
+ return (ord(length[0]) << 8) | ord(length[1])
+
+ @staticmethod
+ def _readLength4(filestream):
+ length = BitFile._readOrDie(filestream, 4)
+
+ return (ord(length[0]) << 24) | (ord(length[1]) << 16) | (ord(length[2]) << 8) | ord(length[3])
+
+ # Read length bytes, or throw an exception
+ @staticmethod
+ def _readOrDie(filestream, length):
+ data = filestream.read(length)
+
+ if len(data) < length:
+ raise BitFileReadError()
+
+ return data
+
+ @staticmethod
+ def _readField(filestream, key):
+ if BitFile._readOrDie(filestream, 1) != key:
+ raise BitFileReadError()
+
+ length = BitFile._readLength(filestream)
+ data = BitFile._readOrDie(filestream, length)
+
+ return data
+
+
+ def __init__(self):
+ self.designname = None
+ self.part = None
+ self.date = None
+ self.time = None
+ self.length = None
+ self.bitstream = None
+
View
507 FT232R-JTAG.old/ft232rjtag.py
@@ -0,0 +1,507 @@
+# NOTE: Only use FT232RJTAG with the 'with' statement, ala:
+# with FT232RJTAG() as jtag:
+# blah blah blah...
+#
+# This ensures that FT232R devices are properly closed,
+# and don't end up in a locked or useless state.
+#
+
+import d2xx
+import time
+
+BIT_TCK = 3# 7 # RI
+BIT_TMS = 2#6 # DCD
+BIT_TDI = 1#5 # DSR
+BIT_TDO = 0#4 # DTR
+
+# Spartan 6, -2, -3N, -3N speed grades
+TMS_TDI_TSU = 10 # 10ns setup time before rising TCK
+TMS_TDI_TH = 5.5 # 5.5ns hold time after rising TCK
+TDO_VALID = 6.5 # 6.5ns after falling TCK, TDO becomes valid
+TCK_MIN = 30 # TCK period must be at least 30ns (<33MHz)
+
+DEFAULT_FREQUENCY = 100 # Hz
+
+# Calculate actual TCK_MIn in seconds
+#TCK_MIN = max(1.0 / DESIRED_FREQUENCY, TCK_MIN * 0.000000001)
+
+# A dictionary, which allows us to look up a jtag device's IDCODE and see
+# how big its Instruction Register is (how many bits). This is entered manually
+# but could, in the future, be read automatically from a database of BSDL files.
+irlength_lut = {0x403d093: 6, 0x401d093: 6, 0x5057093: 16, 0x5059093: 16};
+
+
+class FT232RJTAG_Exception(Exception):
+ def __init__(self, value):
+ self.parameter = value
+ def __str__(self):
+ return repr(self.parameter)
+
+
+class FT232RJTAG:
+ def __init__(self):
+ self.setFrequency(DEFAULT_FREQUENCY)
+
+ self.handle = None
+ self.deviceCount = None
+ self.idcodes = None
+ self.irlengths = None
+ self.debug = 0
+ self.synchronous = None
+ self.async_record = None
+
+ def __enter__(self):
+ return self
+
+ # Be sure to close the opened handle, if there is one.
+ # The device may become locked if we don't (requiring an unplug/plug cycle)
+ def __exit__(self, exc_type, exc_value, traceback):
+ self.close()
+
+ return False
+
+ def _log(self, msg, level=1):
+ if level <= self.debug:
+ print "FT232RJTAG: " + msg
+
+ def open(self, devicenum):
+ if self.handle:
+ raise FT232RJTAG_Exception("A device is already open. Either call Close, or create another FT232RJTAG instance.")
+
+ self.handle = d2xx.open(devicenum)
+
+ if self.handle is not None:
+ self._setSyncMode()
+ self._purgeBuffers() # Just in case
+
+ def close(self):
+ if self.handle is None:
+ return
+
+ self._log("Closing device...")
+
+ try:
+ self.handle.close()
+ finally:
+ self.handle = None
+
+ self._log("Device closed.")
+
+ # Run a stress test of the JTAG chain to make sure communications
+ # will run properly.
+ # This amounts to running the readChain function a hundred times.
+ # Communication failure will be seen as an exception.
+ def stressTest(self, testcount=100):
+ self._log("Stress testing...", 0)
+
+ self.readChain()
+ oldDeviceCount = self.deviceCount
+
+ for i in range(testcount):
+ self.readChain()
+
+ if self.deviceCount != oldDeviceCount:
+ FT232RJTAG_Exception("Stress Test Failed. Device count did not match between iterations.")
+
+ complete = i * 100 / testcount
+ old_complete = (i - 1) * 100 / testcount
+
+ if (i > 0) and (complete > 0) and (complete != old_complete):
+ self._log("%i%% Complete" % complete, 0)
+
+ self._log("Stress test complete. Everything worked correctly.", 0)
+
+ # Purges the FT232R's buffers.
+ def _purgeBuffers(self):
+ if self.handle is None:
+ raise FT232RJTAG_Exception("No device open.")
+
+ self.handle.purge()
+
+ # Put the FT232R into Synchronous mode.
+ def _setSyncMode(self):
+ if self.handle is None:
+ raise FT232RJTAG_Exception("No device open.")
+
+ self._log("Device entering Synchronous mode.")
+
+ self.handle.setBitMode((1 << BIT_TCK) | (1 << BIT_TMS) | (1 << BIT_TDI), 0)
+ self.handle.setBitMode((1 << BIT_TCK) | (1 << BIT_TMS) | (1 << BIT_TDI), 4)
+ self._updateBaudrate()
+ self.synchronous = True
+
+ def _updateBaudrate(self):
+ # Documentation says that we should set a baudrate 16 times lower than
+ # the desired transfer speed (for bit-banging). However I found this to
+ # not be the case. 3Mbaud is the maximum speed of the FT232RL
+ self.handle.setBaudRate(3000000)
+ #self.handle.setDivisor(0) # Another way to set the maximum speed.
+
+
+ # Put the FT232R into Asynchronous mode.
+ def _setAsyncMode(self):
+ if self.handle is None:
+ raise FT232RJTAG_Exception("No device open.")
+
+ self._log("Device entering Asynchronous mode.")
+
+ self.handle.setBitMode((1 << BIT_TCK) | (1 << BIT_TMS) | (1 << BIT_TDI), 0)
+ self.handle.setBitMode((1 << BIT_TCK) | (1 << BIT_TMS) | (1 << BIT_TDI), 1)
+ self._updateBaudrate()
+ self.synchronous = False
+
+ def _formatJtagState(self, tck, tms, tdi):
+ return chr(((tck&1) << BIT_TCK) | ((tms&1) << BIT_TMS) | ((tdi&1) << BIT_TDI))
+
+ def _intJtagState(self, tck, tms, tdi):
+ return ((tck&1) << BIT_TCK) | ((tms&1) << BIT_TMS) | ((tdi&1) << BIT_TDI)
+
+ #def sendJtagState(self, tck, tms, tdi):
+ # if self.handle is None:
+ # return False
+#
+# tck = tck & 1
+# tms = tms & 1
+# tdi = tdi & 1
+#
+# try:
+# x = (tck << BIT_TCK) | (tms << BIT_TMS) | (tdi << BIT_TDI)
+# self.handle.write(chr(x))
+#
+# except Exception, e:
+# print e
+# return False
+#
+# return True
+#
+# def getJtagTdo(self):
+# if self.handle is None:
+# return None
+#
+# tdo = None
+#
+# try:
+# tdo = (self.handle.getBitMode() >> BIT_TDO) & 1
+#
+# except Exception, e:
+# tdo = None
+# print e
+#
+# return tdo
+
+ # Perform a single JTAG clock, and return TDO.
+ # Use for Synchronous mode.
+ def jtagClock(self, tms=0, tdi=0):
+ if self.handle is None:
+ raise FT232RJTAG_Exception("No device open.")
+
+ #self._log("jtagClock %i %i" % (tms, tdi), 0)
+
+ # Bring clock low, high, and then keep high for an extra cycle.
+ # In sync mode, FT232R reads just before setting the data,
+ # hence the extra cycle to correctly read TDO (after tck goes high).
+ data = self._formatJtagState(0, tms, tdi)
+ data += self._formatJtagState(1, tms, tdi)
+
+ if self.async_record is not None:
+ self.async_record += data
+ return None
+
+ data += self._formatJtagState(1, tms, tdi)
+ self.handle.write(data)
+
+ # The last byte
+ result = self.handle.read(3)
+
+ return (ord(result[2]) >> BIT_TDO) & 1
+
+ #self.sendJtagState(0, tms, tdi)
+ #time.sleep(self.tck_min)
+ #self.sendJtagState(1, tms, tdi)
+ #time.sleep(self.tck_min)
+
+ #return self.getJtagTdo()
+
+ def _formatJtagClock(self, tms=0, tdi=0):
+ return self._formatJtagState(0, tms, tdi) + self._formatJtagState(1, tms, tdi)
+
+ # TODO: Why is the data sent backwards!?!?!
+ # NOTE: It seems that these are designed specifically for Xilinx's
+ # weird bit ordering when reading various registers. Most specifically,
+ # bitstreams are sent MSB first.
+ def sendByte(self, val, last=True):
+ if self.handle is None:
+ raise FT232RJTAG_Exception("No device open.")
+
+ for n in range(7, -1, -1):
+ self.jtagClock((n == 0) & last, (val >> n) & 1)
+
+ def readByte(self, val, last=True):
+ if self.handle is None:
+ raise FT232RJTAG_Exception("No device open.")
+
+ result = 0
+
+ for n in range(7, -1, -1):
+ bit = self.jtagClock((n == 0) & last, (val >> n) & 1)
+ result |= bit << (7 - n)
+
+ return result
+
+ def tapReset(self):
+ if self.handle is None:
+ raise FT232RJTAG_Exception("No device open.")
+
+ for i in range(0, 6):
+ self.jtagClock(tms=1)
+
+ def readChain(self):
+ if self.handle is None:
+ raise FT232RJTAG_Exception("No device open.")
+
+ self.deviceCount = None
+ self.idcodes = None
+ self.irlengths = None
+
+ self._readDeviceCount()
+ self._readIdcodes()
+ self._processIdcodes()
+
+ def _readDeviceCount(self):
+ if self.handle is None:
+ raise FT232RJTAG_Exception("No device open.")
+
+ self.deviceCount = None
+
+ self.tapReset()
+ # Shift-IR
+ self.jtagClock(tms=0)
+ self.jtagClock(tms=1)
+ self.jtagClock(tms=1)
+ self.jtagClock(tms=0)
+ self.jtagClock(tms=0)
+
+ # Force BYPASS
+ for i in range(0, 100): # TODO should be 1000
+ self.jtagClock(tms=0, tdi=1)
+ self.jtagClock(tms=1, tdi=1)
+
+ # Shift-DR
+ self.jtagClock(tms=1, tdi=1)
+ self.jtagClock(tms=1, tdi=1)
+ self.jtagClock(tms=0, tdi=1)
+ self.jtagClock(tms=0, tdi=1)
+
+ # Flush DR registers
+ for i in range(0, 100):
+ self.jtagClock(tms=0, tdi=0)
+
+ # Count the number of devices
+ for i in range(0, 100):
+ if self.jtagClock(tms=0, tdi=1) == 1:
+ self.deviceCount = i
+ break
+
+ self.tapReset()
+
+ if self.deviceCount is None:
+ raise FT232RJTAG_Exception("Could not find any devices in the JTAG chain.")
+
+
+ def _readIdcodes(self):
+ if self.handle is None:
+ raise FT232RJTAG_Exception("No device open.")
+
+ if self.deviceCount is None:
+ raise FT232RJTAG_Exception("Can't read IDCODEs until the device count is known.")
+
+ self.idcodes = []
+
+ self.tapReset()
+
+ # Shift-DR
+ self.jtagClock(tms=0)
+ self.jtagClock(tms=1)
+ self.jtagClock(tms=0)
+ self.jtagClock(tms=0)
+
+ for d in range(0, self.deviceCount):
+ idcode = self.readByte(0xFF, False)
+ idcode |= self.readByte(0xFF, False) << 8
+ idcode |= self.readByte(0xFF, False) << 16
+ idcode |= self.readByte(0xFF, d == (self.deviceCount-1)) << 24
+
+ self.idcodes.insert(0, idcode)
+
+ self.tapReset()
+
+ def _processIdcodes(self):
+ if self.idcodes is None:
+ raise FT232RJTAG_Exception("No IDCODEs have been read.")
+
+ self.irlengths = []
+
+ for idcode in self.idcodes:
+ if (idcode & 0x0FFFFFFF) in irlength_lut:
+ self.irlengths.append(irlength_lut[idcode & 0x0FFFFFFF])
+ else:
+ self.irlengths = None
+ raise FT232RJTAG_Exception("Unknown IDCODE: %.8X. IRlength is unknown." % idcode)
+
+
+ @staticmethod
+ def decodeIdcode(idcode):
+ if (idcode & 1) != 1:
+ print "Warning: Bit 0 of IDCODE is not 1. Not a valid Xilinx IDCODE."
+
+ manuf = (idcode >> 1) & 0x07ff
+ size = (idcode >> 12) & 0x01ff
+ family = (idcode >> 21) & 0x007f
+ rev = (idcode >> 28) & 0x000f
+
+ print "Device ID: %.8X" % idcode
+ print "Manuf: %x, Part Size: %x, Family Code: %x, Revision: %0d" % (manuf, size, family, rev)
+
+ # Desired JTAG Frequency in Hz
+ def setFrequency(self, freq):
+ self.tck_min = max(1.0 / freq, TCK_MIN * 0.000000001)
+
+ def buildInstruction(self, deviceid, instruction):
+ if self.irlengths is None:
+ raise FT232RJTAG_Exception("IRLengths are unknown.")
+
+ result = []
+
+ for d in range(self.deviceCount - 1, -1, -1):
+ for i in range(0, self.irlengths[d]):
+ if d == deviceid:
+ result.append(instruction & 1)
+ instruction = instruction >> 1
+ else:
+ result.append(1)
+
+ return result
+
+ # Load an instruction into a single device, BYPASSing the others.
+ # Leaves the TAP at IDLE.
+ def singleDeviceInstruction(self, deviceid, instruction):
+ self.tapReset()
+
+ self.jtagClock(tms=0)
+ self.jtagClock(tms=1)
+ self.jtagClock(tms=1)
+ self.jtagClock(tms=0)
+ self.jtagClock(tms=0)
+
+ bits = self.buildInstruction(deviceid, instruction)
+ #print bits, len(bits)
+ self.jtagWriteBits(bits, last=True)
+
+ self.jtagClock(tms=1)
+ self.jtagClock(tms=0)
+
+ # TODO: Currently assumes that deviceid is the last device in the chain.
+ # TODO: Assumes TAP is in IDLE state.
+ # Leaves the device in IDLE state.
+ def shiftDR(self, deviceid, bits):
+ self.jtagClock(tms=1)
+ self.jtagClock(tms=0)
+ self.jtagClock(tms=0)
+
+ readback = self.jtagWriteBits(bits, last=(self.deviceCount==1))
+
+ for d in range(self.deviceCount-2):
+ self.jtagClock(tms=0)
+
+ if self.deviceCount > 1:
+ self.jtagClock(tms=1)
+
+ self.jtagClock(tms=1)
+ self.jtagClock(tms=0)
+
+ return readback
+
+ # TODO: Perform in a single D2XX.Write call.
+ # TODO: ^ Be careful not to fill the RX buffer (128 bytes).
+ def jtagWriteBits(self, bits, last=False):
+ readback = []
+
+ for b in bits[:-1]:
+ readback.append(self.jtagClock(tdi=b, tms=0))
+ readback.append(self.jtagClock(tdi=bits[-1], tms=(last&1)))
+
+ return readback
+
+ # Read the Configuration STAT register
+ def readConfigStat(self, deviceid):
+ if self.handle is None:
+ return None
+
+ if self.irlengths is None:
+ return None
+
+ extraDevices = deviceid
+
+ self.tapReset()
+
+ self.jtagClock(tms=0)
+ self.jtagClock(tms=1)
+ self.jtagClock(tms=1)
+ self.jtagClock(tms=0)
+ self.jtagClock(tms=0)
+
+ self.jtagWriteBits(self.buildInstruction(deviceid, 5))
+
+ self.jtagClock(tms=1)
+ self.jtagClock(tms=1)
+ self.jtagClock(tms=0)
+ self.jtagClock(tms=0)
+
+ for x in [0xAA, 0x99, 0x55, 0x66, 0x29, 0x01, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20]:
+ self.sendByte(x, False)
+ self.sendByte(0x00, extraDevices==0)
+
+ for i in range(0, extraDevices):
+ if i == (extraDevices-1):
+ self.jtagClock(tdi=1, tms=1)
+ else:
+ self.jtagClock(tdi=1)
+
+ self.jtagClock(tms=1)
+ self.jtagClock(tms=1)
+ self.jtagClock(tms=1)
+ self.jtagClock(tms=0)
+ self.jtagClock(tms=0)
+
+ self.jtagWriteBits(self.buildInstruction(deviceid, 4))
+
+ self.jtagClock(tms=1)
+ self.jtagClock(tms=1)
+ self.jtagClock(tms=0)
+ self.jtagClock(tms=0)
+
+ stat = 0
+
+ for i in range(0, 15+(len(self.irlengths)-deviceid)):
+ stat = (stat << 1) | self.jtagClock()
+ stat = (stat << 1) | self.jtagClock(tms=1)
+
+ self.tapReset()
+
+ return stat & 0xFFFF
+
+ # Read the Configuration STAT register
+ def sendJprogram(self, deviceid):
+ if self.handle is None or self.irlengths is None:
+ raise FT232RJTAG_Exception("IRLengths is None.")
+
+ self.singleDeviceInstruction(deviceid, 0xB)
+
+ self.tapReset()
+ self.tapReset()
+ self.tapReset()
+ self.tapReset()
+
+
+
+
View
267 FT232R-JTAG.old/main.py
@@ -0,0 +1,267 @@
+from ft232rjtag import FT232RJTAG
+from BitstreamReader import BitFile, BitFileReadError
+import time
+import traceback
+import struct
+
+
+### BitFile ###
+print "Reading BIT file..."
+bitfile = None
+
+try:
+ with open('bitstream/fpgaminer_USER1_50MH.bit', 'rb') as f:
+ bitfile = BitFile.read(f)
+
+except BitFileReadError, e:
+ print e
+ exit()
+
+print "Design Name:\t", bitfile.designname
+print "Part Name:\t", bitfile.part
+print "Date:\t", bitfile.date
+print "Time:\t", bitfile.time
+print "Bitstream Length:\t", len(bitfile.bitstream)
+print "\n"
+
+
+### JTAG ###
+with FT232RJTAG() as jtag:
+ jtag.open(0)
+ #if not jtag.open(0):
+ # print "Unable to open the JTAG communication device. Is the board attached by USB?"
+ # exit()
+
+ print "Discovering JTAG Chain..."
+ idcodes = jtag.readChain()
+
+ print "There are %i devices in the JTAG chain." % len(jtag.idcodes)
+
+ for idcode in jtag.idcodes:
+ FT232RJTAG.decodeIdcode(idcode)
+
+ if jtag.irlengths is None:
+ print "Not all devices in the chain are known. Cannot program."
+ jtag.close()
+ exit()
+
+ print "\n"
+
+ #print jtag.readConfigStat(2)
+
+ #jtag.tapReset()
+
+ # Shift-IR
+ #jtag.jtagClock(tms=0)
+ #jtag.jtagClock(tms=1)
+ #jtag.jtagClock(tms=1)
+ #jtag.jtagClock(tms=0)
+ #jtag.jtagClock(tms=0)
+
+ # Build instruction
+ # TODO: Construct based on the device chain
+ #jtag.jtagClock(tdi=1)
+ #jtag.jtagClock(tdi=0)
+ #jtag.jtagClock(tdi=0)
+ #jtag.jtagClock(tdi=1)
+ #jtag.jtagClock(tdi=0)
+ #jtag.jtagClock(tdi=0)
+ #
+ #for i in range(0, 31):
+ # jtag.jtagClock(tdi=1)
+ #
+ #jtag.jtagClock(tdi=1,tms=1)
+ #
+ #jtag.jtagClock(tms=1, tdi=1)
+ #jtag.jtagClock(tms=1, tdi=1)
+ #jtag.jtagClock(tms=0, tdi=1)
+ #jtag.jtagClock(tms=0, tdi=1)
+ #
+ ## Flush DR registers
+ #print "0x%.2X" % jtag.readByte(0xFF, False)
+ #print "0x%.2X" % jtag.readByte(0xFF, False)
+ #print "0x%.2X" % jtag.readByte(0xFF, False)
+ #print "0x%.2X" % jtag.readByte(0xFF, False)
+ #
+ #print jtag.readByte(0xFF, False)
+ #print jtag.readByte(0xFF, False)
+ #print jtag.readByte(0xFF, False)
+ #print jtag.readByte(0xFF, False)
+ #
+ #print jtag.readByte(0xFF, False)
+ #print jtag.readByte(0xFF, False)
+ #print jtag.readByte(0xFF, False)
+ #print jtag.readByte(0xFF, True)
+ #
+ #jtag.tapReset()
+
+
+ print "Beginning programming..."
+
+ jtag.sendJprogram(2)
+
+ jtag.tapReset()
+
+ # Shift-IR
+ #jtag.jtagClock(tms=0)
+ #jtag.jtagClock(tms=1)
+ #jtag.jtagClock(tms=1)
+ #jtag.jtagClock(tms=0)
+ #jtag.jtagClock(tms=0)
+
+ # CFG_IN
+ jtag.singleDeviceInstruction(jtag.deviceCount-1, 0b000101)
+
+ # Build instruction - CFG_IN
+ # TODO: Construct based on the device chain
+ #jtag.jtagClock(tdi=1)
+ #jtag.jtagClock(tdi=0)
+ #jtag.jtagClock(tdi=1)
+ #jtag.jtagClock(tdi=0)
+ #jtag.jtagClock(tdi=0)
+ #jtag.jtagClock(tdi=0)
+
+ #for i in range(0, 31):
+ # jtag.jtagClock(tdi=1)
+
+ #jtag.jtagClock(tdi=1,tms=1)
+
+ # Shift-DR
+ #jtag.jtagClock(tms=1, tdi=1)
+ jtag.jtagClock(tms=1, tdi=1)
+ jtag.jtagClock(tms=0, tdi=1)
+ jtag.jtagClock(tms=0, tdi=1)
+
+
+ bytetotal = len(bitfile.bitstream)
+
+ jtagstr = ""
+
+ (rxlen, txlen, events) = jtag.handle.getStatus()
+ print rxlen, txlen, events
+
+ jtag._setAsyncMode()
+
+ # Prepare all data to be transfered
+ chunk = None
+ chunk_i = 0
+ data_chunks = []
+ CHUNK_SIZE = 4096*4
+
+ start_time = time.time()
+
+ for n in range(0, bytetotal):
+ d = ord(bitfile.bitstream[n])
+
+ if chunk is None:
+ bytesleft = (bytetotal - n) * 16
+ chunk = bytearray(min(CHUNK_SIZE, bytesleft))
+
+ for i in range(7, -1, -1):
+ x = (d >> i) & 1
+ chunk[chunk_i] = jtag._intJtagState(0, 0, x)
+ chunk[chunk_i+1] = jtag._intJtagState(1, 0, x)
+ chunk_i += 2
+
+ if chunk_i == CHUNK_SIZE:
+ data_chunks.append(chunk.decode())
+ chunk_i = 0
+ chunk = None
+
+ if chunk is not None:
+ data_chunks.append(chunk.decode())
+
+ #jtagstr += struct.pack("=16c", jtag._formatJtagState(0, 0, (d>>7)&1), jtag._formatJtagState(1, 0, (d>>7)&1), jtag._formatJtagState(0, 0, (d>>6)&1), jtag._formatJtagState(1, 0, (d>>6)&1), jtag._formatJtagState(0, 0, (d>>5)&1), jtag._formatJtagState(1, 0, (d>>5)&1), jtag._formatJtagState(0, 0, (d>>4)&1), jtag._formatJtagState(1, 0, (d>>4)&1), jtag._formatJtagState(0, 0, (d>>3)&1), jtag._formatJtagState(1, 0, (d>>3)&1), jtag._formatJtagState(0, 0, (d>>2)&1), jtag._formatJtagState(1, 0, (d>>2)&1), jtag._formatJtagState(0, 0, (d>>1)&1), jtag._formatJtagState(1, 0, (d>>1)&1), jtag._formatJtagState(0, 0, (d)&1), jtag._formatJtagState(1, 0, (d)&1))
+
+ #for i in range(7, -1, -1):
+ # x = (d >> i) & 1
+ # jtagstr += struct.pack("=cccccccccccccccc", jtag._intJtagState(0, 0, ), jtag._intJtagState(1, 0, x))
+ # #jtagstr += jtag._formatJtagState(0, 0, (d >> i) & 1) + jtag._formatJtagState(1, 0, (d >> i) & 1)
+
+ #if len(jtagstr) == 1024:
+ # data_chunks.append(jtagstr)
+ # jtagstr = ""
+
+ #if len(jtagstr) > 0:
+ # data_chunks.append(jtagstr)
+
+ print "Pre-processing took %i seconds." % int(time.time() - start_time)
+
+ # Now transfer all data to the FPGA
+ written = 0
+ last_time = time.time()
+ for n in range(len(data_chunks)):
+ chunk = data_chunks[n]
+
+ jtag.handle.write(chunk)
+ written += len(chunk) / 16
+
+ if (written % (16 * 1024)) == 0:
+ print "Completed: ", str((written * 1000 / bytetotal) * 0.1), "%"
+ print str(written * 1.0 / (time.time() - last_time)), "B/s"
+
+ #(rxlen, txlen, events) = jtag.handle.getStatus()
+ #print rxlen, txlen, events
+
+ print "Total Time: %i secs." % int(time.time() - last_time)
+ print "Last write"
+
+ #if len(jtagstr) > 0:
+ # jtag.handle.write(jtagstr)
+
+ (rxlen, txlen, events) = jtag.handle.getStatus()
+ print rxlen, txlen, events
+
+ print "Switching modes..."
+ jtag._purgeBuffers()
+ jtag._setSyncMode()
+ print "Mode switched."
+
+ #jtag.tck_min = old_sleep
+
+ # An extra two shifts because of the other two devices
+ jtag.jtagClock(tdi=1, tms=0)
+ jtag.jtagClock(tdi=1, tms=1)
+
+
+ jtag.jtagClock(tms=1) # Update-DR
+ jtag.jtagClock(tms=1) # Select-DR
+ jtag.jtagClock(tms=1) # Select-IR
+ jtag.jtagClock(tms=0) # Shift-IR
+ jtag.jtagClock(tms=0) # Shift-IR
+
+ # J-START
+ jtag.jtagClock(tms=0, tdi=0)
+ jtag.jtagClock(tms=0, tdi=0)
+ jtag.jtagClock(tms=0, tdi=1)
+ jtag.jtagClock(tms=0, tdi=1)
+ jtag.jtagClock(tms=0, tdi=0)
+ jtag.jtagClock(tms=0, tdi=0)
+
+ for i in range(0, 31):
+ jtag.jtagClock(tdi=1)
+
+ jtag.jtagClock(tdi=1,tms=1)
+
+ jtag.jtagClock(tms=1) # Update-IR
+
+ # Go to RTI and clock there for at least 16 cycles
+ for n in range(0, 17):
+ jtag.jtagClock(tms=0)
+
+ # Move to TLR. Device should now be functional.
+ jtag.jtagClock(tms=1)
+ jtag.jtagClock(tms=1)
+ jtag.jtagClock(tms=1)
+ jtag.jtagClock(tms=1)
+
+ print "Programming complete!?!?"
+
+ #print jtag.readConfigStat(2)
+
+
+
+#jtag.close()
+
+print "Finished"
+
View
465 FT232R-JTAG.old/miner.py
@@ -0,0 +1,465 @@
+from ft232rjtag import FT232RJTAG
+import time
+import traceback
+from base64 import b64encode
+from json import dumps, loads
+from threading import Thread
+from Queue import Queue, Empty
+import httplib
+import socket
+
+# Socket wrapper to enable socket.TCP_NODELAY and KEEPALIVE
+realsocket = socket.socket
+def socketwrap(family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0):
+ sockobj = realsocket(family, type, proto)
+ sockobj.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
+ sockobj.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
+ return sockobj
+socket.socket = socketwrap
+
+
+class NotAuthorized(Exception): pass
+class RPCError(Exception): pass
+
+class Object(object):
+ pass
+
+USER_INSTRUCTION = 0b000010
+current_job = None
+
+# Convert a hex string into an array of bytes
+def hexstr2array(hexstr):
+ arr = []
+
+ for i in range(len(hexstr)/2):
+ arr.append((int(hexstr[i*2], 16) << 4) | int(hexstr[i*2+1], 16))
+
+ return arr
+
+# Convert an integer to an array of bits.
+# LSB first.
+def int2bits(i, bits):
+ result = []
+
+ for n in range(bits):
+ result.append(i & 1)
+ i = i >> 1
+
+ return result
+
+# LSB first.
+def bits2int(bits):
+ x = 0
+
+ for i in range(len(bits)):
+ x |= bits[i] << i
+
+ return x
+
+def fpgaReadByte(jtag):
+ byte = jtag.shiftDR(jtag.deviceCount-1, int2bits(0, 13))
+ byte = bits2int(byte)
+
+ print "Read: %.04X" % byte
+
+ if byte < 0x1000:
+ return None
+
+ return byte
+
+def fpgaReadNonce(jtag):
+ jtag.singleDeviceInstruction(jtag.deviceCount-1, USER_INSTRUCTION)
+
+ # Sync to the beginning of a nonce.
+ # The MSB is a VALID flag. If 0, data is invalid (queue empty).
+ # The next 4-bits indicate which byte of the nonce we got.
+ # 1111 is LSB, and then 0111, 0011, 0001.
+ byte = None
+ while True:
+ byte = fpgaReadByte(jtag)
+
+ if byte is None:
+ jtag.tapReset()
+ return None
+
+ if (byte & 0xF00) == 0b111100000000:
+ break
+
+ # We now have the first byte
+ nonce = byte & 0xFF
+ count = 1
+ print "Potential nonce, reading the rest..."
+ while True:
+ byte = fpgaReadByte(jtag)
+
+ if byte is None:
+ continue
+
+ nonce |= (byte & 0xFF) << (count * 8)
+ count += 1
+
+ if (byte & 0xF00) == 0b000100000000:
+ break
+
+ jtag.tapReset()
+
+ print "Nonce completely read: %.08X" % nonce
+
+ return nonce
+
+# TODO: This may not actually clear the queue, but should be correct most of the time.
+def fpgaClearQueue(jtag):
+ print "Clearing queue"
+
+ while True:
+ jtag.tapReset() # Gives extra time for the FPGA's FIFO to get the next byte ready.
+
+ if fpgaReadNonce(jtag) is None:
+ break
+
+ print "Queue cleared"
+
+writejob_jtagstr = ""
+
+
+def fpgaWriteJob(jtag, job):
+ # We need the 256-bit midstate, and 12 bytes from data.
+ # The first 64 bytes of data are already hashed (hence midstate),
+ # so we skip that. Of the last 64 bytes, 52 bytes are constant and
+ # not needed by the FPGA.
+ midstate = hexstr2array(job.midstate)
+ data = hexstr2array(job.data)[64:64+12]
+
+ # Job's hex strings are LSB first, and the FPGA wants them MSB first.
+ midstate.reverse()
+ data.reverse()
+
+ print "Loading job data..."
+
+ t1 = time.time()
+ jtag._setAsyncMode()
+ jtag.async_record = ""
+
+ jtag.singleDeviceInstruction(jtag.deviceCount-1, USER_INSTRUCTION)
+
+ data = midstate + data + [0]
+
+ for i in range(len(data)):
+ x = data[i]
+
+ if i != 0:
+ x = 0x100 | x
+
+ jtag.shiftDR(jtag.deviceCount-1, int2bits(x, 13))
+
+ jtag.tapReset()
+
+ print "It took %f seconds to record async data." % (time.time() - t1)
+
+ t1 = time.time()
+ jtag.handle.write(jtag.async_record)
+ jtag.async_record = None
+ jtag._setSyncMode()
+ jtag._purgeBuffers()
+
+ print "It took %f seconds to write async data." % (time.time() - t1)
+
+
+ print "Job data loaded."
+
+
+#
+#def readNonce(jtag):
+# jtag.singleDeviceInstruction(jtag.deviceCount-1, USER_INSTRUCTION)
+#
+# data = jtag.shiftDR(jtag.deviceCount-1, int2bits(0, 13))
+# nonce = bits2int(data)
+#
+# jtag.tapReset()
+#
+# return "%.04X" % nonce
+
+def connect(proto, host, timeout):
+ connector = httplib.HTTPSConnection if proto == 'https' else httplib.HTTPConnection
+
+ return connector(host, strict=True, timeout=timeout)
+
+def request(connection, url, headers, data=None):
+ result = response = None
+
+ try:
+ if data is not None:
+ connection.request('POST', url, data, headers)
+ else:
+ connection.request('GET', url, headers=headers)
+
+ response = connection.getresponse()
+
+ if response.status == httplib.UNAUTHORIZED:
+ raise NotAuthorized()
+
+ result = loads(response.read())
+
+ if result['error']:
+ raise RPCError(result['error']['message'])
+
+ return (connection, result)
+ finally:
+ if not result or not response or (response.version == 10 and response.getheader('connection', '') != 'keep-alive') or response.getheader('connection', '') == 'close':
+ connection.close()
+ connection = None
+
+def failure(msg):
+ print msg
+ exit()
+
+def getwork(connection, data=None):
+ try:
+ if not connection:
+ connection = connect(proto, host, timeout)
+
+ postdata['params'] = [data] if data is not None else []
+ (connection, result) = request(connection, '/', headers, dumps(postdata))
+
+ return (connection, result['result'])
+ except NotAuthorized:
+ failure('Wrong username or password.')
+ except RPCError as e:
+ print e
+ except (IOError, httplib.HTTPException, ValueError):
+ print "Problems communicating with bitcoin RPC."
+
+ return (connection, None)
+
+def sendGold(connection, gold):
+ hexnonce = hex(gold.nonce)[8:10] + hex(gold.nonce)[6:8] + hex(gold.nonce)[4:6] + hex(gold.nonce)[2:4]
+ data = gold.job.data[:128+24] + hexnonce + gold.job.data[128+24+8:]
+
+ print "Nonce: ", gold.nonce
+ print "Hexnonce: ", hexnonce
+ print "Original Data: " + gold.job.data
+ print "Nonced Data: " + data
+
+ (connection, accepted) = getwork(connection, data)
+ if accepted is not None:
+ if accepted == True:
+ print "accepted"
+ else:
+ print "_rejected_"
+
+ return connection
+
+
+def getworkloop():
+ connection = None
+ last_job = None
+
+ while True:
+ time.sleep(0.1)
+
+ if last_job is None or (time.time() - last_job) > 20:
+ last_job = time.time()
+
+ (connection, work) = getwork(connection)
+
+ if work is not None:
+ job = Object()
+ job.midstate = work['midstate']
+ job.data = work['data']
+
+ jobqueue.put(job)
+
+ gold = None
+ try:
+ gold = goldqueue.get(False)
+ except Empty:
+ gold = None
+
+ if gold is not None:
+ print "SUBMITTING GOLDEN TICKET"
+ connection = sendGold(connection, gold)
+
+
+
+
+proto = "http"
+host = "mining.eligius.st:8337"
+postdata = {'method': 'getwork', 'id': 'json'}
+headers = {"User-Agent": 'Bitcoin Dominator ALPHA', "Authorization": 'Basic ' + b64encode('1Kbu8PdP2xK45zygVrY3qv9icw6zGjaiWu:x')}
+timeout = 5
+jobqueue = Queue()
+goldqueue = Queue()
+
+
+with FT232RJTAG() as jtag:
+ jtag.open(0)
+ #if not jtag.open(0):
+ #print "Unable to open the JTAG communication device. Is the board attached by USB?"
+ #exit()
+
+ print "Discovering JTAG Chain..."
+ jtag.readChain()
+
+ print "There are %i devices in the JTAG chain." % len(jtag.idcodes)
+
+ for idcode in jtag.idcodes:
+ FT232RJTAG.decodeIdcode(idcode)
+
+ if jtag.irlengths is None:
+ print "Not all devices in the chain are known. Cannot program."
+ jtag.close()
+ exit()
+
+ print "\n"
+
+ #midstate = hexstr2array("228ea4732a3c9ba860c009cda7252b9161a5e75ec8c582a5f106abb3af41f790")
+ #data = hexstr2array("2194261a9395e64dbed17115")
+ #data = hexstr2array("2194261a9395e64dbed17132")
+
+ #print "Loading test data..."
+
+ #jtag.singleDeviceInstruction(jtag.deviceCount-1, USER_INSTRUCTION)
+
+ #data = midstate + data + [0]
+
+ #for i in range(len(data)):
+ # x = data[i]
+#
+# if i != 0:
+# x = 0x100 | x
+#
+# jtag.shiftDR(jtag.deviceCount-1, int2bits(x, 13))
+#
+# jtag.tapReset()
+#
+# print "Test data loaded.\n"
+#
+#
+
+# connection = None
+
+
+
+ # Start HTTP thread
+ thread = Thread(target=getworkloop)
+ thread.daemon = True
+ thread.start()
+
+ #job = Object()
+ #job.midstate = "90f741afb3ab06f1a582c5c85ee7a561912b25a7cd09c060a89b3c2a73a48e22"
+ #job.data = "000000014cc2c57c7905fd399965282c87fe259e7da366e035dc087a0000141f000000006427b6492f2b052578fb4bc23655ca4e8b9e2b9b69c88041b2ac8c771571d1be4de695931a2694217a33330e000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000"
+
+ #jobqueue.put(job)
+
+ while True:
+ time.sleep(1.1)
+
+ job = None
+
+ try:
+ job = jobqueue.get(False)
+ except Empty:
+ job = None
+
+ if job is not None:
+ t1 = time.time()
+ fpgaWriteJob(jtag, job)
+ fpgaClearQueue(jtag)
+ current_job = job
+ print "Writing took %i seconds." % (time.time() - t1)
+
+ t1 = time.time()
+ nonce = fpgaReadNonce(jtag)
+ print "Reading took %i seconds." % (time.time() - t1)
+
+ if nonce is not None:
+ print "FOUND GOLDEN TICKET"
+ gold = Object()
+ gold.job = current_job
+ gold.nonce = nonce
+
+ goldqueue.put(gold)
+
+
+ #time.sleep(1)
+ #print readNonce(jtag)
+
+ #fpgaReadNonce(jtag)
+ #fpgaClearQueue(jtag)
+ #fpgaWriteJob(jtag, job)
+
+#def readyForUser2(jtag):
+# jtag.tapReset()
+#
+# jtag.jtagClock(tms=0)
+# jtag.jtagClock(tms=1)
+# jtag.jtagClock(tms=1)
+# jtag.jtagClock(tms=0)
+# jtag.jtagClock(tms=0)
+#
+# jtag.jtagClock(tdi=0)
+# jtag.jtagClock(tdi=1)
+# jtag.jtagClock(tdi=0)
+# jtag.jtagClock(tdi=0)
+# jtag.jtagClock(tdi=0)
+# jtag.jtagClock(tdi=0)
+#
+# for i in range(0, 31):
+# jtag.jtagClock(tdi=1)
+#
+# jtag.jtagClock(tdi=1,tms=1)
+#
+# # Shift-DR
+# jtag.jtagClock(tms=1, tdi=1)
+# jtag.jtagClock(tms=1, tdi=1)
+# jtag.jtagClock(tms=0, tdi=1)
+# jtag.jtagClock(tms=0, tdi=1)
+#
+#readyForUser2(jtag)
+#
+#data = midstate + data + [0]
+#
+#for i in range(0, len(data)):
+# x = data[i]
+#
+# if i != 0:
+# x = 0x100 | x
+#
+# for j in range(13):
+# jtag.jtagClock(tdi=(x&1))
+# x >>= 1
+#
+# jtag.jtagClock(tdi=0)
+# jtag.jtagClock(tdi=0, tms=1)
+# jtag.jtagClock(tdi=0, tms=1)
+# jtag.jtagClock(tdi=0, tms=1)
+# jtag.jtagClock(tdi=0, tms=0)
+# jtag.jtagClock(tdi=0, tms=0)
+#
+#jtag.tapReset()
+#
+#print "Test data loaded.\n"
+#
+#def readNonce(jtag):
+# readyForUser2(jtag)
+#
+# x = 0
+#
+# for i in range(0, 13):
+# x |= jtag.jtagClock(tdi=0) << i
+#
+# jtag.jtagClock(tdi=0)
+# jtag.jtagClock(tdi=0, tms=1)
+#
+# jtag.tapReset()
+#
+# return "%.04X" % x
+#
+#
+#while True:
+# time.sleep(1)
+# print readNonce(jtag)
+#
+#jtag.close()
+#
+#
View
10 FT232R-JTAG.old/stress_test.py
@@ -0,0 +1,10 @@
+from ft232rjtag import FT232RJTAG
+
+with FT232RJTAG() as jtag:
+ jtag.open(0)
+ #if not jtag.open(0):
+ #print "Unable to open the JTAG communication device. Is the board attached by USB?"
+ #exit()
+
+ jtag.stressTest()
+
View
2  TAP.py
@@ -47,7 +47,7 @@ class TAP:
def __init__(self, jtagClock):
self.jtagClock = jtagClock
self.state = None
- self.debug = 1
+ self.debug = 0
def reset(self):
for i in range(6):
View
45 bugcheck.py
@@ -0,0 +1,45 @@
+import d2xx
+import time
+
+def safe_read(handle, count):
+ while handle.getQueueStatus() < count:
+ time.sleep(1)
+ print "Waiting to read..."
+
+ return handle.read(count)
+
+
+print "Openning"
+handle = d2xx.open(0)
+handle.setBitMode(0x0F, 0)
+handle.setBitMode(0x0F, 4)
+handle.setBaudRate(3000000)
+
+print "Write and read?"
+handle.write("\x00"*100)
+safe_read(handle, 100)
+
+handle.setBitMode(0x0F, 0)
+handle.setBitMode(0x0F, 1)
+
+
+print "Writing"
+CHUNK_SIZE = 4096*4
+for i in range(16000000/CHUNK_SIZE):
+ print "Wrote: ", handle.write("\x00"*CHUNK_SIZE)
+
+print handle.getStatus()
+print handle.getQueueStatus()
+
+handle.setBitMode(0x0F, 0)
+handle.setBitMode(0x0f, 4)
+handle.purge(0)
+
+print "Write and read?"
+handle.write("\x00"*100)
+safe_read(handle, 100)
+
+
+
+handle.close()
+
View
14 ft232r.py
@@ -1,6 +1,7 @@
import d2xx
import struct
from TAP import TAP
+import time
DEFAULT_FREQUENCY = 3000000
@@ -70,7 +71,7 @@ def _purgeBuffers(self):
if self.handle is None:
raise DeviceNotOpened()
- self.handle.purge(1)
+ self.handle.purge(0)
def _setBaudRate(self, rate):
self._log("Setting baudrate to %i" % rate)
@@ -138,6 +139,7 @@ def readTDO(self, num):
# Write all data that we don't care about.
if len(self.write_buffer) > 0:
+ print "Flushing out %i" % len(self.write_buffer)
self.flush()
self._purgeBuffers()
@@ -146,8 +148,16 @@ def readTDO(self, num):
while len(write_buffer) > 0:
written = min(len(write_buffer), 3072)
- self.handle.write(write_buffer[:written])
+ print written
+ print len(write_buffer)
+ print "Wrote: ", self.handle.write(write_buffer[:written])
write_buffer = write_buffer[written:]
+ print self.handle.getStatus()
+ print self.handle.getQueueStatus()
+
+ while self.handle.getQueueStatus() < written:
+ time.sleep(1)
+ print self.handle.getQueueStatus()
read = self.handle.read(written)
for n in range(written/3):
View
33 jtag.py
@@ -85,9 +85,7 @@ def reset(self):
#self.shift_ir()
self.tap.reset()
- def shift_ir(self):
- print self.current_instructions
-
+ def shift_ir(self, read=False):
self.tap.goto(TAP.SELECT_IR)
self.tap.goto(TAP.SHIFT_IR)
@@ -95,7 +93,14 @@ def shift_ir(self):
self.jtagClock(tdi=bit)
self.jtagClock(tdi=self.current_instructions[-1], tms=1)
+ self._tckcount = 0
self.tap.goto(TAP.IDLE)
+
+ if read:
+ return self.readTDO(len(self.current_instructions)+self._tckcount)[:-self._tckcount]
+
+ def read_ir(self):
+ return self.shift_ir(read=True)
# TODO: Doesn't work correctly if not operating on the last device in the chain
def shift_dr(self, bits, read=False):
@@ -130,6 +135,7 @@ def bulk_shift_dr(self, data, progressCallback=None):
self.tap.goto(TAP.SELECT_DR)
self.tap.goto(TAP.SHIFT_DR)
self.flush()
+ print self.handle.getQueueStatus()
bytetotal = len(data)
@@ -163,20 +169,30 @@ def bulk_shift_dr(self, data, progressCallback=None):
chunks.append(chunk)
print "Processed. Writing..."
+ print self.handle.getQueueStatus()
self._setAsyncMode()
written = 0
start_time = time.time()
for chunk in chunks:
- self.handle.write(chunk)
+ wrote = self.handle.write(chunk)
+ if wrote != len(chunk):
+ print "...THAT'S WEIRD!!! %i" % wrote
written += len(chunk) / 16
if (written % (16 * 1024)) == 0 and progressCallback:
progressCallback(start_time, written, bytetotal)
+ progressCallback(start_time, written, bytetotal)
+
+ print self.handle.getStatus()
+ print self.handle.getQueueStatus()
self._setSyncMode()
self._purgeBuffers()
+ print self.handle.getQueueStatus()
+
+ print self.handle.getStatus()
for bit in last_bits[:-1]:
self.jtagClock(tdi=bit)
@@ -184,6 +200,15 @@ def bulk_shift_dr(self, data, progressCallback=None):
self.tap.goto(TAP.IDLE)
self.flush()
+ print self.handle.getQueueStatus()
+ print self.handle.getStatus()
+ #self.handle.resetDevice()
+ #self._setSyncMode()
+ #self.close()
+ #self.open(0)
+ #self._setSyncMode()
+ #print self.handle.getQueueStatus()
+ #print self.handle.getStatus()
def __enter__(self):
View
20 program.py
@@ -85,34 +85,44 @@ def bitstreamProgress(start_time, written, total):
jtag.flush()
+ #print ord(bitfile.bitstream[5000])
+ #bitfile.bitstream = bitfile.bitstream[0:5000] + chr(0x12) + bitfile.bitstream[5001:]
+
# Load bitstream into CFG_IN
jtag.bulk_shift_dr(bitfile.bitstream, bitstreamProgress)
# Load with JSTART
jtag.instruction(0x0C)
jtag.shift_ir()
+ print "a"
# Let the device start
jtag.runtest(24)
+ print "b"
# Load with Bypass
jtag.instruction(0xFF)
jtag.shift_ir()
jtag.instruction(0xFF)
jtag.shift_ir()
+ print "c"
# Load with JSTART
jtag.instruction(0x0C)
jtag.shift_ir()
+ print "d"
jtag.runtest(24)
+ print "e"
+
# Check done pin
- # TODO: jtag.instruction(0xFF)
- # TODO: jtag.read_ir() & 0x20 == 0x21
- # jtag.instruction(0xFF)
- # jtag.shift_ir()
- # jtag.shift_dr([0])
+ jtag.instruction(0xFF)
+ # TODO: Figure this part out. & 0x20 should equal 0x20 to check the DONE pin ... ???
+ print jtag.read_ir() # & 0x20 == 0x21
+ jtag.instruction(0xFF)
+ jtag.shift_ir()
+ jtag.shift_dr([0])
jtag.flush()
Please sign in to comment.
Something went wrong with that request. Please try again.