def __init__(self, ft232r, chain, logger): self.jobqueue = Queue() self.ft232r = ft232r self.chain = chain self.jtag = JTAG(ft232r, chain) self.logger = logger self.id = -1 self.current_job = None self.last_job = 0 self.nonce_count = 0 self.valid_count = 0 self.invalid_count = 0 self.accepted_count = 0 self.rejected_count = 0 self.recent_valids = 0 self.asleep = True self.firmware_rev = 0 self.firmware_build = 0
logger.fpga_list = fpga_list rpcclient.fpga_list = fpga_list for id, fpga in enumerate(fpga_list): fpga.id = id logger.reportDebug("Discovering FPGA %d..." % id, False) fpga.detect() logger.reportDebug( "Found %i device%s:" % (fpga.jtag.deviceCount, "s" if fpga.jtag.deviceCount != 1 else ""), False ) if len(fpga.jtag.idcodes) > 0: idcode = fpga.jtag.idcodes[-1] msg = " FPGA" + str(id) + ": " msg += JTAG.decodeIdcode(idcode) msg += " - Firmware: rev " + str(fpga.firmware_rev) msg += ", build " + str(fpga.firmware_build) logger.reportDebug(msg, False) logger.log("Connected to %d FPGAs" % len(fpga_list), False) if settings.overclock is not None: for fpga in fpga_list: fpga.setClockSpeed(settings.overclock) for fpga in fpga_list: clock_speed = fpga.readClockSpeed() clock_speed = "???" if clock_speed is None else str(clock_speed)
fpga.id = id logger.reportDebug("Discovering FPGA %d ..." % id, False) fpga.detect() logger.reportDebug("Found %i device%s:" % (fpga.jtag.deviceCount, 's' if fpga.jtag.deviceCount != 1 else ''), False) if fpga.jtag.deviceCount > 1: logger.log("Warning:", False) logger.log("This software currently supports only one device per chain.", False) logger.log("Only the last part will be programmed.", False) if fpga.jtag.deviceCount > 0: idcode = fpga.jtag.idcodes[-1] msg = " FPGA" + str(id) + ": " msg += JTAG.decodeIdcode(idcode) logger.reportDebug(msg, False) if idcode & 0x0FFFFFFF != bitfile.idcode: raise BitFileMismatch logger.log("Connected to %d FPGAs" % len(fpga_list), False) if settings.chain == 2: jtag = JTAG(ft232r, settings.chain) jtag.deviceCount = 1 jtag.idcodes = [bitfile.idcode] jtag._processIdcodes() else: jtag = fpga_list[0].jtag if bitfile.processed[settings.chain]:
class FPGA: def __init__(self, ft232r, chain, logger): self.jobqueue = Queue() self.ft232r = ft232r self.chain = chain self.jtag = JTAG(ft232r, chain) self.logger = logger self.id = -1 self.current_job = None self.last_job = 0 self.nonce_count = 0 self.valid_count = 0 self.invalid_count = 0 self.accepted_count = 0 self.rejected_count = 0 self.recent_valids = 0 self.asleep = True self.firmware_rev = 0 self.firmware_build = 0 def detect(self): with self.ft232r.lock: self.jtag.detect() # Always use the last part in the chain if self.jtag.deviceCount > 0: self.jtag.part(self.jtag.deviceCount-1) usercode = self._readUserCode() if usercode == 0xFFFFFFFF: self.firmware_rev = 0 self.firmware_build = 0 else: self.firmware_rev = (usercode >> 8) & 0xFF self.firmware_build = usercode & 0xFF # Read the FPGA's USERCODE register, which gets set by the firmware # In our case this should be 0xFFFFFFFF for all old firmware revs, # and 0x4224???? for newer revs. The 2nd byte determines firmware rev/version, # and the 1st byte determines firmware build. def _readUserCode(self): with self.ft232r.lock: if self.asleep: self.wake() self.jtag.tap.reset() self.jtag.instruction(USERCODE) self.jtag.shift_ir() usercode = bits2int(self.jtag.read_dr(int2bits(0, 32))) return usercode # Old JTAG Comm: def _readByte(self): bits = int2bits(0, 13) byte = bits2int(self.jtag.read_dr(bits)) return byte # New JTAG Comm # Read a 32-bit register def _readRegister(self, address): address = address & 0xF with self.ft232r.lock: if self.asleep: self.wake() self.jtag.tap.reset() self.jtag.instruction(USER_INSTRUCTION) self.jtag.shift_ir() # Tell the FPGA what address we would like to read data = int2bits(address, 5) data = data + jtagcomm_checksum(data) self.jtag.shift_dr(data) # Now read back the register data = self.jtag.read_dr(int2bits(0, 32)) data = bits2int(data) self.jtag.tap.reset() return data # Write a single 32-bit register # If doing multiple writes, this won't be as efficient def _writeRegister(self, address, data): address = address & 0xF data = data & 0xFFFFFFFF with self.ft232r.lock: if self.asleep: self.wake() self.jtag.tap.reset() self.jtag.instruction(USER_INSTRUCTION) self.jtag.shift_ir() # Tell the FPGA what address we would like to write # and the data. data = int2bits(data, 32) + int2bits(address, 4) + [1] data = data + jtagcomm_checksum(data) self.jtag.shift_dr(data) self.jtag.tap.reset() self.ft232r.flush() def _burstWriteHelper(self, address, data): address = address & 0xF x = int2bits(data, 32) x += int2bits(address, 4) x += [1] x = x + jtagcomm_checksum(x) self.jtag.shift_dr(x) # Writes multiple 32-bit registers. # data should be an array of 32-bit values # address is the starting address. # TODO: Implement readback of some kind to ensure all our writes succeeded. # TODO: This is difficult, because reading back data will slow things down. # TODO: If the JTAG class let us read data back after a shift, we could probably # TODO: use that at the end of the burst write. def _burstWrite(self, address, data): with self.ft232r.lock: if self.asleep: self.wake() self.jtag.tap.reset() self.jtag.instruction(USER_INSTRUCTION) self.jtag.shift_ir() for offset in range(len(data)): self._burstWriteHelper(address + offset, data[offset]) self.jtag.tap.reset() self.ft232r.flush() return True # TODO: Remove backwards compatibility in a future rev. def _old_readNonce(self): with self.ft232r.lock: if self.asleep: self.wake() self.jtag.tap.reset() self.jtag.instruction(USER_INSTRUCTION) self.jtag.shift_ir() self.asleep = False # 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 = self._readByte() # check data valid bit: if byte < 0x1000: self.jtag.tap.reset() return None #self.logger.reportDebug("%d: Read: %04x" % (self.id, byte)) # check byte counter: if (byte & 0xF00) == 0xF00: break # We now have the first byte nonce = byte & 0xFF count = 1 #self.logger.reportDebug("%d: Potential nonce, reading the rest..." % self.id) while True: byte = self._readByte() #self.logger.reportDebug("%d: Read: %04x" % (self.id, byte)) # check data valid bit: if byte < 0x1000: self.jtag.tap.reset() return None # check byte counter: if (byte & 0xF00) >> 8 != (0xF >> count): self.jtag.tap.reset() return None nonce |= (byte & 0xFF) << (count * 8) count += 1 if (byte & 0xF00) == 0x100: break self.jtag.tap.reset() #self.logger.reportDebug("%d: Nonce completely read: %08x" % (self.id, nonce)) return nonce # TODO: This may not actually clear the queue, but should be correct most of the time. def _old_clearQueue(self): with self.ft232r.lock: if self.asleep: self.wake() self.jtag.tap.reset() self.jtag.instruction(USER_INSTRUCTION) self.jtag.shift_ir() self.asleep = False self.logger.reportDebug("%d: Clearing queue..." % self.id) while True: if self._readByte() < 0x1000: break self.jtag.tap.reset() self.logger.reportDebug("%d: Queue cleared" % self.id) def _old_writeJob(self, 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. start_time = time.time() 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() with self.ft232r.lock: #self.logger.reportDebug("%d: Loading job data..." % self.id) if self.asleep: self.wake() self.jtag.tap.reset() self.jtag.instruction(USER_INSTRUCTION) self.jtag.shift_ir() data = midstate + data + [0] for i in range(len(data)): x = data[i] if i != 0: x = 0x100 | x self.jtag.shift_dr(int2bits(x, 13)) self.jtag.tap.reset() self.ft232r.flush() #self.logger.reportDebug("%d: Job data loaded in %.3f seconds" % (self.id, time.time() - start_time)) self.logger.reportDebug("%d: Job data loaded" % self.id) def _readNonce(self): nonce = self._readRegister(0xE) if nonce == 0xFFFFFFFF: return None return nonce def _clearQueue(self): self.logger.reportDebug("%d: Clearing queue..." % self.id) while True: if self.readNonce() is None: break self.logger.reportDebug("%d: Queue cleared" % self.id) def _writeJob(self, 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. start_time = time.time() midstate = hexstr2array(job.midstate) data = hexstr2array(job.data)[64:64+12] data = midstate + data words = [] for i in range(11): word = data[i*4] | (data[i*4+1] << 8) | (data[i*4+2] << 16) | (data[i*4+3] << 24) words.append(word) if not self._burstWrite(1, words): self.logger.reportDebug("%d: ERROR: Loading job data failed; readback failure" % self.id) return self.logger.reportDebug("%d: Job data loaded in %.3f seconds" % (self.id, time.time() - start_time)) #self.logger.reportDebug("%d: Job data loaded" % self.id) # Read the FPGA's current clock speed, in MHz # NOTE: This is currently just what we've written into the clock speed # register, so it does NOT take into account hard limits in the firmware. def readClockSpeed(self): if self.firmware_rev == 0: return None frequency = self._readRegister(0xD) return frequency # Set the FPGA's clock speed, in MHz # NOTE: Be VERY careful not to set the clock speed too high!!! def setClockSpeed(self, speed): if self.firmware_rev == 0: return False return self._writeRegister(0xD, speed) def readNonce(self): if self.firmware_rev == 0: return self._old_readNonce() else: return self._readNonce() def clearQueue(self): if self.firmware_rev == 0: return self._old_clearQueue() else: return self._clearQueue() def writeJob(self, job): if self.firmware_rev == 0: return self._old_writeJob(job) else: return self._writeJob(job) def getJob(self): try: #logger.reportDebug("%d: Checking for new job..." % fpga.id) return self.jobqueue.get(False) except Empty: return None def putJob(self, work): job = Object() job.midstate = work['midstate'] job.data = work['data'] job.target = work['target'] self.jobqueue.put(job) #self.logger.reportDebug("%d: jobqueue loaded (%d)" % (fpga.id, self.jobqueue.qsize())) def sleep(self): with self.ft232r.lock: self.logger.reportDebug("%d: Going to sleep..." % self.id) self.jtag.tap.reset() self.jtag.instruction(JSHUTDOWN) self.jtag.shift_ir() self.jtag.runtest(24) self.jtag.tap.reset() self.ft232r.flush() self.asleep = True def wake(self): with self.ft232r.lock: self.logger.reportDebug("%d: Waking up..." % self.id) self.jtag.tap.reset() self.jtag.instruction(JSTART) self.jtag.shift_ir() self.jtag.runtest(24) self.jtag.instruction(BYPASS) self.jtag.shift_ir() self.jtag.instruction(BYPASS) self.jtag.shift_ir() self.jtag.instruction(JSTART) self.jtag.shift_ir() self.jtag.runtest(24) self.jtag.tap.reset() self.ft232r.flush() self.asleep = False @staticmethod def programBitstream(ft232r, jtag, logger, processed_bitstream): with ft232r.lock: # Select the device jtag.reset() jtag.part(jtag.deviceCount-1) jtag.instruction(BYPASS) jtag.shift_ir() jtag.instruction(JPROGRAM) jtag.shift_ir() jtag.instruction(CFG_IN) jtag.shift_ir() # Clock TCK for 10000 cycles jtag.runtest(10000) jtag.instruction(CFG_IN) jtag.shift_ir() jtag.shift_dr([0]*32) jtag.instruction(CFG_IN) jtag.shift_ir() ft232r.flush() # Load bitstream into CFG_IN jtag.load_bitstream(processed_bitstream, logger.updateProgress) jtag.instruction(JSTART) jtag.shift_ir() # Let the device start jtag.runtest(24) jtag.instruction(BYPASS) jtag.shift_ir() jtag.instruction(BYPASS) jtag.shift_ir() jtag.instruction(JSTART) jtag.shift_ir() jtag.runtest(24) # Check done pin #jtag.instruction(BYPASS) # TODO: Figure this part out. & 0x20 should equal 0x20 to check the DONE pin ... ??? #print jtag.read_ir() # & 0x20 == 0x21 #jtag.instruction(BYPASS) #jtag.shift_ir() #jtag.shift_dr([0]) ft232r.flush()
logger.reportDebug( "Found %i device%s:" % (fpga.jtag.deviceCount, 's' if fpga.jtag.deviceCount != 1 else ''), False) if fpga.jtag.deviceCount > 1: logger.log("Warning:", False) logger.log( "This software currently supports only one device per chain.", False) logger.log("Only the last part will be programmed.", False) if fpga.jtag.deviceCount > 0: idcode = fpga.jtag.idcodes[-1] msg = " FPGA" + str(id) + ": " msg += JTAG.decodeIdcode(idcode) logger.reportDebug(msg, False) if idcode & 0x0FFFFFFF != bitfile.idcode: raise BitFileMismatch logger.log("Connected to %d FPGAs" % len(fpga_list), False) if settings.chain == 2: jtag = JTAG(ft232r, settings.chain) jtag.deviceCount = 1 jtag.idcodes = [bitfile.idcode] jtag._processIdcodes() else: jtag = fpga_list[0].jtag if bitfile.processed[settings.chain]:
rpcclient.fpga_list = fpga_list for id, fpga in enumerate(fpga_list): fpga.id = id logger.reportDebug("Discovering FPGA %d..." % id, False) fpga.detect() logger.reportDebug( "Found %i device%s:" % (fpga.jtag.deviceCount, 's' if fpga.jtag.deviceCount != 1 else ''), False) if len(fpga.jtag.idcodes) > 0: idcode = fpga.jtag.idcodes[-1] msg = " FPGA" + str(id) + ": " msg += JTAG.decodeIdcode(idcode) msg += " - Firmware: rev " + str(fpga.firmware_rev) msg += ", build " + str(fpga.firmware_build) logger.reportDebug(msg, False) logger.log("Connected to %d FPGAs" % len(fpga_list), False) if settings.overclock is not None: for fpga in fpga_list: fpga.setClockSpeed(settings.overclock) for fpga in fpga_list: clock_speed = fpga.readClockSpeed() clock_speed = "???" if clock_speed is None else str(clock_speed)
class FPGA: def __init__(self, ft232r, chain, logger): self.jobqueue = Queue() self.ft232r = ft232r self.chain = chain self.jtag = JTAG(ft232r, chain) self.logger = logger self.id = -1 self.current_job = None self.last_job = 0 self.nonce_count = 0 self.valid_count = 0 self.invalid_count = 0 self.accepted_count = 0 self.rejected_count = 0 self.recent_valids = 0 self.asleep = True self.firmware_rev = 0 self.firmware_build = 0 def detect(self): with self.ft232r.lock: self.jtag.detect() # Always use the last part in the chain if self.jtag.deviceCount > 0: self.jtag.part(self.jtag.deviceCount - 1) usercode = self._readUserCode() if usercode == 0xFFFFFFFF: self.firmware_rev = 0 self.firmware_build = 0 else: self.firmware_rev = (usercode >> 8) & 0xFF self.firmware_build = usercode & 0xFF # Read the FPGA's USERCODE register, which gets set by the firmware # In our case this should be 0xFFFFFFFF for all old firmware revs, # and 0x4224???? for newer revs. The 2nd byte determines firmware rev/version, # and the 1st byte determines firmware build. def _readUserCode(self): with self.ft232r.lock: if self.asleep: self.wake() self.jtag.tap.reset() self.jtag.instruction(USERCODE) self.jtag.shift_ir() usercode = bits2int(self.jtag.read_dr(int2bits(0, 32))) return usercode # Old JTAG Comm: def _readByte(self): bits = int2bits(0, 13) byte = bits2int(self.jtag.read_dr(bits)) return byte # New JTAG Comm # Read a 32-bit register def _readRegister(self, address): address = address & 0xF with self.ft232r.lock: if self.asleep: self.wake() self.jtag.tap.reset() self.jtag.instruction(USER_INSTRUCTION) self.jtag.shift_ir() # Tell the FPGA what address we would like to read data = int2bits(address, 5) data = data + jtagcomm_checksum(data) self.jtag.shift_dr(data) # Now read back the register data = self.jtag.read_dr(int2bits(0, 32)) data = bits2int(data) self.jtag.tap.reset() return data # Write a single 32-bit register # If doing multiple writes, this won't be as efficient def _writeRegister(self, address, data): address = address & 0xF data = data & 0xFFFFFFFF with self.ft232r.lock: if self.asleep: self.wake() self.jtag.tap.reset() self.jtag.instruction(USER_INSTRUCTION) self.jtag.shift_ir() # Tell the FPGA what address we would like to write # and the data. data = int2bits(data, 32) + int2bits(address, 4) + [1] data = data + jtagcomm_checksum(data) self.jtag.shift_dr(data) self.jtag.tap.reset() self.ft232r.flush() def _burstWriteHelper(self, address, data): address = address & 0xF x = int2bits(data, 32) x += int2bits(address, 4) x += [1] x = x + jtagcomm_checksum(x) self.jtag.shift_dr(x) # Writes multiple 32-bit registers. # data should be an array of 32-bit values # address is the starting address. # TODO: Implement readback of some kind to ensure all our writes succeeded. # TODO: This is difficult, because reading back data will slow things down. # TODO: If the JTAG class let us read data back after a shift, we could probably # TODO: use that at the end of the burst write. def _burstWrite(self, address, data): with self.ft232r.lock: if self.asleep: self.wake() self.jtag.tap.reset() self.jtag.instruction(USER_INSTRUCTION) self.jtag.shift_ir() for offset in range(len(data)): self._burstWriteHelper(address + offset, data[offset]) self.jtag.tap.reset() self.ft232r.flush() return True # TODO: Remove backwards compatibility in a future rev. def _old_readNonce(self): with self.ft232r.lock: if self.asleep: self.wake() self.jtag.tap.reset() self.jtag.instruction(USER_INSTRUCTION) self.jtag.shift_ir() self.asleep = False # 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 = self._readByte() # check data valid bit: if byte < 0x1000: self.jtag.tap.reset() return None #self.logger.reportDebug("%d: Read: %04x" % (self.id, byte)) # check byte counter: if (byte & 0xF00) == 0xF00: break # We now have the first byte nonce = byte & 0xFF count = 1 #self.logger.reportDebug("%d: Potential nonce, reading the rest..." % self.id) while True: byte = self._readByte() #self.logger.reportDebug("%d: Read: %04x" % (self.id, byte)) # check data valid bit: if byte < 0x1000: self.jtag.tap.reset() return None # check byte counter: if (byte & 0xF00) >> 8 != (0xF >> count): self.jtag.tap.reset() return None nonce |= (byte & 0xFF) << (count * 8) count += 1 if (byte & 0xF00) == 0x100: break self.jtag.tap.reset() #self.logger.reportDebug("%d: Nonce completely read: %08x" % (self.id, nonce)) return nonce # TODO: This may not actually clear the queue, but should be correct most of the time. def _old_clearQueue(self): with self.ft232r.lock: if self.asleep: self.wake() self.jtag.tap.reset() self.jtag.instruction(USER_INSTRUCTION) self.jtag.shift_ir() self.asleep = False self.logger.reportDebug("%d: Clearing queue..." % self.id) while True: if self._readByte() < 0x1000: break self.jtag.tap.reset() self.logger.reportDebug("%d: Queue cleared" % self.id) def _old_writeJob(self, 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. start_time = time.time() 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() with self.ft232r.lock: #self.logger.reportDebug("%d: Loading job data..." % self.id) if self.asleep: self.wake() self.jtag.tap.reset() self.jtag.instruction(USER_INSTRUCTION) self.jtag.shift_ir() data = midstate + data + [0] for i in range(len(data)): x = data[i] if i != 0: x = 0x100 | x self.jtag.shift_dr(int2bits(x, 13)) self.jtag.tap.reset() self.ft232r.flush() #self.logger.reportDebug("%d: Job data loaded in %.3f seconds" % (self.id, time.time() - start_time)) self.logger.reportDebug("%d: Job data loaded" % self.id) def _readNonce(self): nonce = self._readRegister(0xE) if nonce == 0xFFFFFFFF: return None return nonce def _clearQueue(self): self.logger.reportDebug("%d: Clearing queue..." % self.id) while True: if self.readNonce() is None: break self.logger.reportDebug("%d: Queue cleared" % self.id) def _writeJob(self, 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. start_time = time.time() # blakecoin DEBUG #midstatehex = '' #proc = subprocess.Popen(['./midstate',job.data],stdout=subprocess.PIPE) # OK for linux and windows #while True: # msline = proc.stdout.readline() # if (msline != ''): # midstatehex = msline.rstrip() # else: # break #print "\nmidstatehex=", midstatehex #midstate1 = hexstr2array(midstatehex) #print (midstate1) midstate_blake8 = BLAKE(256).midstate( struct.pack("<16I", *struct.unpack(">16I", job.data.decode('hex')[:64]))) # print('\nmidstate_blake8 %s' % (hexlify(midstate_blake8).decode())) midstate_blake8_swap = struct.pack( "<8I", *struct.unpack(">8I", midstate_blake8)) # print('\nmidswap_blake8 %s' % (hexlify(midstate_blake8_swap).decode())) # midstate = hexstr2array(job.midstate) // ORIGINAL midstate = hexstr2array(hexlify(midstate_blake8_swap).decode()) # print (midstate) data = hexstr2array(job.data)[64:64 + 12] data = midstate + data words = [] for i in range(11): word = data[i * 4] | (data[i * 4 + 1] << 8) | ( data[i * 4 + 2] << 16) | (data[i * 4 + 3] << 24) words.append(word) if not self._burstWrite(1, words): self.logger.reportDebug( "%d: ERROR: Loading job data failed; readback failure" % self.id) return self.logger.reportDebug("%d: Job data loaded in %.3f seconds" % (self.id, time.time() - start_time)) #self.logger.reportDebug("%d: Job data loaded" % self.id) # Read the FPGA's current clock speed, in MHz # NOTE: This is currently just what we've written into the clock speed # register, so it does NOT take into account hard limits in the firmware. def readClockSpeed(self): if self.firmware_rev == 0: return None frequency = self._readRegister(0xD) return frequency # Set the FPGA's clock speed, in MHz # NOTE: Be VERY careful not to set the clock speed too high!!! def setClockSpeed(self, speed): if self.firmware_rev == 0: return False return self._writeRegister(0xD, speed) def readNonce(self): if self.firmware_rev == 0: return self._old_readNonce() else: return self._readNonce() def clearQueue(self): if self.firmware_rev == 0: return self._old_clearQueue() else: return self._clearQueue() def writeJob(self, job): if self.firmware_rev == 0: return self._old_writeJob(job) else: return self._writeJob(job) def getJob(self): try: #logger.reportDebug("%d: Checking for new job..." % fpga.id) return self.jobqueue.get(False) except Empty: return None def putJob(self, work): job = Object() # Commented out midstate as pool does not supply it, which causes getwork error # (its not needed as midstate is calculated locally) # job.midstate = work['midstate'] job.data = work['data'] job.target = work['target'] self.jobqueue.put(job) #self.logger.reportDebug("%d: jobqueue loaded (%d)" % (fpga.id, self.jobqueue.qsize())) def sleep(self): with self.ft232r.lock: self.logger.reportDebug("%d: Going to sleep..." % self.id) self.jtag.tap.reset() self.jtag.instruction(JSHUTDOWN) self.jtag.shift_ir() self.jtag.runtest(24) self.jtag.tap.reset() self.ft232r.flush() self.asleep = True def wake(self): with self.ft232r.lock: self.logger.reportDebug("%d: Waking up..." % self.id) self.jtag.tap.reset() self.jtag.instruction(JSTART) self.jtag.shift_ir() self.jtag.runtest(24) self.jtag.instruction(BYPASS) self.jtag.shift_ir() self.jtag.instruction(BYPASS) self.jtag.shift_ir() self.jtag.instruction(JSTART) self.jtag.shift_ir() self.jtag.runtest(24) self.jtag.tap.reset() self.ft232r.flush() self.asleep = False @staticmethod def programBitstream(ft232r, jtag, logger, processed_bitstream): with ft232r.lock: # Select the device jtag.reset() jtag.part(jtag.deviceCount - 1) jtag.instruction(BYPASS) jtag.shift_ir() jtag.instruction(JPROGRAM) jtag.shift_ir() jtag.instruction(CFG_IN) jtag.shift_ir() # Clock TCK for 10000 cycles jtag.runtest(10000) jtag.instruction(CFG_IN) jtag.shift_ir() jtag.shift_dr([0] * 32) jtag.instruction(CFG_IN) jtag.shift_ir() ft232r.flush() # Load bitstream into CFG_IN jtag.load_bitstream(processed_bitstream, logger.updateProgress) jtag.instruction(JSTART) jtag.shift_ir() # Let the device start jtag.runtest(24) jtag.instruction(BYPASS) jtag.shift_ir() jtag.instruction(BYPASS) jtag.shift_ir() jtag.instruction(JSTART) jtag.shift_ir() jtag.runtest(24) # Check done pin #jtag.instruction(BYPASS) # TODO: Figure this part out. & 0x20 should equal 0x20 to check the DONE pin ... ??? #print jtag.read_ir() # & 0x20 == 0x21 #jtag.instruction(BYPASS) #jtag.shift_ir() #jtag.shift_dr([0]) ft232r.flush()