📄 dongle.py
字号:
buf=don.getReturn(2) # two bytes expected to this command
if ord(buf[1])==0x32 and ord(buf[0])==0x10:
print "Dongle OK"
else:
print 'Dongle returned on open: %02x %02x '%(ord(buf[1]), ord(buf[0]))
don.write_command(0x01C5) #try getting dongle HW ver (works since 05 before that returns 0x3210)
buf=don.getReturn(2) # two bytes expected to this command
if ord(buf[1])==0x86 and ord(buf[0])>0x04:
mode.version = ord(buf[0])
don.mode = mode
print 'Dongle HW version code is %02x %02x'%(ord(buf[1]), ord(buf[0]))
else:
don.mode = mode
print 'Dongle HW version code is smaller than 05 some features have been improved on'
print 'HW code and Quartus FPGA binary file are available at:'
print 'http://www.opencores.org/projects.cgi/web/usb_dongle_fpga/overview'
print 'Programming is possible with Altera Quartus WE and BYTEBLASTER II cable or'
print 'compatible clone like X-Blaster http://www.customcircuitsolutions.com/cable.html'
if mode.q == 1: # perform a query from dongle
buf=don.read_data(4,0x0) # word count and word address
don.write_command(0x0050) # 0x0098
don.write_command(0x0098) # 0x0098
buf=don.read_data(3,0x000010) # word count and word address
if ord(buf[0])==0x51 and ord(buf[2])==0x52 and ord(buf[4])==0x59:
buf=don.read_data(2,0x000000) # word count and word address
print 'Query OK, Flash Factory Code is: 0x%02x device: 0x%02x '%(ord(buf[0]),ord(buf[2]))
buf=don.read_data(2,0x000002)
print 'lock bit is 0x%02x 0x%02x'%(ord(buf[0]),ord(buf[1]))
else:
print "Got bad Flash query data:"
print 'Query address 0x10 = 0x%02x%02x '%(ord(buf[1]),ord(buf[0]))
print 'Query address 0x12 = 0x%02x%02x '%(ord(buf[3]),ord(buf[2]))
print 'Query address 0x14 = 0x%02x%02x '%(ord(buf[5]),ord(buf[4]))
print "Read byte count:",len(buf)
don.write_command(0x00FF) # 0x0098
buf=don.read_data(4,0xff57c0>>1) # word count and word address
print 'Data: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x '%(ord(buf[1]),ord(buf[0]),ord(buf[3]),ord(buf[2]),ord(buf[5]),ord(buf[4]),ord(buf[7]),ord(buf[6]) )
if mode.filename!="" and mode.address!=-1:
#Calculate number of blocks and start of blocks
size = 0
mode.address = mode.address>>1 #make word address
try:
f=open(mode.filename,"rb")
f.seek(0,2) #seek to end
size = f.tell()
f.seek(0) #seek to start
print 'File size %iK '%(size/1024)
f.close()
except IOError:
print "IO Error on file open. File missing or no premission to open."
sys.exit()
#clear blockLock bits
don.write_command(0x0060) # 0x0098
don.write_command(0x00D0) # 0x0098
if mode.version < 5:
don.wait_on_busy()
don.parse_status()
wordSize = (size+ (size&1))>> 1 # round byte count up and make word address
endBlock = don.get_block_no(mode.address+wordSize - 1)
startBlock = don.get_block_no(mode.address)
if endBlock >= 32:
print "Given file does not fit into remaining space. File size is %i KB"%(size/1024)
print "Space left from given offset is %i KB"%((4*1024*1024-mode.address*2)/1024)
sys.exit()
i=startBlock
print 'Erasing from block %i to %i '%(i,endBlock)
while i <= endBlock:
if mode.v == 1:
print 'Erasing block %i '%(i)
else:
sys.stdout.write(".")
sys.stdout.flush()
don.erase_block(i)
if mode.version < 5:
don.wait_on_busy()
don.parse_status() #do this after programming all but uneaven ending
i=i+1
if mode.v == 0:
print " "
#don.write_command(0x00FF) # 0x0098
#buf=don.read_data(4,0x000000) # word count and word address
#print 'Data: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x '%(ord(buf[0]),ord(buf[1]),ord(buf[2]),ord(buf[3]),ord(buf[4]),ord(buf[5]),ord(buf[6]),ord(buf[7]) )
f=open(mode.filename,"rb")
f.seek(0) #seek to start
address= mode.address
#don.set_address(address)
print 'Writing %iK'%(size/1024)
while 1:
if (address/(1024*64) != (address-16)/(1024*64)) and address != mode.address: # get bytes from words if 512
if mode.v == 1:
print 'Progress: %iK of %iK at 0x%06x'%((address-mode.address)/512,size/1024,address)
else:
sys.stdout.write(".")
sys.stdout.flush()
buf = f.read(32) #16 words is maximum write here bytes are read
if len(buf)==32:
don.buffer_write(16,address,buf)
address = address + 16
elif len(buf)>0:
don.parse_status() #do this after programming all but uneaven ending
print "Doing an unaligned write..."
length = len(buf)
length = (length + (length&1))>> 1 #round up to get even word count
buf = buf+"\xff" #pad just in case rounding took place
don.buffer_write(len,address,buf)
address = address + 16 #inc word address
break
else:
break
if mode.v == 0:
print " "
if mode.version >= 5:
print "Waiting for buffers to empty"
don.wait_on_busy()
don.parse_status() #do this after programming all but uneaven ending
print "Write DONE!"
don.parse_status() #do this after programming all but uneaven ending
f.close()
if mode.r == 1: # perform a readback
if mode.offset!=-1 and mode.length!=-1 and mode.filename!="":
if mode.version >= 5:
##################### from hw ver 5 readback code ##################################################
blockCount = (mode.length>>17)+1 #read this many 64K word blocks
mode.offset=mode.offset>>1 #make word offset
lastLength = mode.length&0x0001FFFF
mode.length= mode.length>>1 #make word length
if mode.length < 512:
print 'Reading %i bytes in single block '%(lastLength)
else:
print 'Reading %iK in %i blocks '%(mode.length/512,blockCount)
don.write_command(0x00FF) # put flash to data read mode
try:
f=open(mode.filename,"wb") #if this fails no point in reading as there is nowhere to write
address = mode.offset # set word address
don.set_address(address)
i=0
while (i<blockCount):
don.issue_blk_read() # request 64K words from current address
buf=don.getReturn(65536*2) #Read all words
if (i==blockCount-1): #last block
f.write(buf[:lastLength])
else:
f.write(buf) ## must tuncate the buffer
if mode.v == 1:
print 'Got block %i'%(i+1)
else:
sys.stdout.write(".")
sys.stdout.flush()
i+=1
f.close()
except IOError:
print "IO Error on file open"
sys.exit()
##################### end from hw ver 5 readback code ############################################
else:
##################### before hw ver 5 readback code ###############################################
mode.offset=mode.offset>>1 #make word offset
mode.length= mode.length>>1 #make word length
print 'Reading %iK'%(mode.length/512)
try:
f=open(mode.filename,"wb")
don.write_command(0x00FF) # put flash to data read mode
address = mode.offset # set word address
while 1:
if address/(1024*32) != (address-128)/(1024*32): # get K bytes from words if 512
if mode.v == 1:
print 'Progress: %iK of %iK'%((address-mode.offset)/512,mode.length/512)
else:
sys.stdout.write(".")
sys.stdout.flush()
buf=don.read_data(128,address) # word count and byte address read 64 words to speed up
f.write(buf)
#print "from address:",address<<1," ", len(buf)
if address+128 >= (mode.offset + mode.length): # 2+64 estimates the end to end in right place
break
address = address + 128 #this is word address
f.close()
if mode.v == 0:
print " "
print "Readback done!"
except IOError:
print "IO Error on file open"
sys.exit()
##################### end before hw ver 5 readback code ################################################
else:
print "Some of readback parameters missing..."
print mode.offset,mode.length, mode.filename
sys.exit()
if mode.t == 1: # perform dongle test
print "Dongle TEST"
if mode.e == 1:
#Erase Dongle
print "Erasing"
don.write_command(0x0060) # 0x0098
don.write_command(0x00D0) # 0x0098
don.wait_on_busy()
don.parse_status()
endBlock = 31
startBlock = 0
i=startBlock
while i <= endBlock:
if mode.v == 1:
print 'Erasing block %i '%(i)
else:
sys.stdout.write(".")
sys.stdout.flush()
don.erase_block(i)
don.wait_on_busy()
don.parse_status() #do this after programming all but uneaven ending
i=i+1
if mode.v == 0: # add CRTL return to dots
print ""
#Do marching one test on data and address
mode.length= 0 #make word length
try:
#Marching one test
#---------------------------------------------------------------------------
address = 0x100000 # set word address
data = 0x100000
while mode.length<20: # last address to test 0x20 0000
buf1=pack('BBBB', (0x000000FF&data),(0x0000FF00&data)>>8 ,(0x00FF0000&data)>>16 ,(0xFF0000&data)>>24 )
don.buffer_write(2,address,buf1)
don.parse_status() #do this after programming all but uneaven ending
don.write_command(0x00FF) # put flash to data read mode
buf2=don.read_data(2,address) # word count and byte address read 64 words to speed up
if buf1 != buf2:
print 'IN %02x %02x %02x %02x '%(ord(buf1[3]), ord(buf1[2]),ord(buf1[1]), ord(buf1[0]))
print 'OUT %02x %02x %02x %02x '%(ord(buf2[3]), ord(buf2[2]),ord(buf2[1]), ord(buf2[0]))
print "Test FAIL!!!!!"
sys.exit()
address = address >> 1
if address == 0x2:
address = address >> 1 # 0x2 is written and will return zero on read as write new write will fail
data = data >> 1
mode.length = mode.length + 1
buf2=don.read_data(1,0) #read first byte
if ord(buf2[0]) != 0xFF:
print "Test FAIL (At least one address line const. 0)!!!!!"
sys.exit()
#-----------------------------------------------------------------------
#Marching zero test
address = 0xFFEFFFFF # set word address
data = 0x100000
while mode.length<18: # last address to test 0x20 0000
buf1=pack('BBBB', (0x000000FF&data),(0x0000FF00&data)>>8 ,(0x00FF0000&data)>>16 ,(0xFF0000&data)>>24 )
don.buffer_write(2,address,buf1)
don.parse_status() #do this after programming all but uneaven ending
don.write_command(0x00FF) # put flash to data read mode
buf2=don.read_data(2,address&0x1FFFFF) # word count and byte address read 64 words to speed up
if buf1 != buf2:
print 'IN %02x %02x %02x %02x '%(ord(buf1[3]), ord(buf1[2]),ord(buf1[1]), ord(buf1[0]))
print 'OUT %02x %02x %02x %02x '%(ord(buf2[3]), ord(buf2[2]),ord(buf2[1]), ord(buf2[0]))
print "Test FAIL!!!!!"
sys.exit()
address = (address >> 1)|0xFF000000
data = data >> 1
mode.length = mode.length + 1
buf2=don.read_data(1,0x1FFFFF) #read first byte
if ord(buf2[0]) != 0xFF:
print "Test FAIL (At least two address lines bonded)!!!!!"
sys.exit()
if mode.b == 1:
#Erase Dongle
print "Erasing"
don.write_command(0x0060) # 0x0098
don.write_command(0x00D0) # 0x0098
don.wait_on_busy()
don.parse_status()
endBlock = 31
startBlock = 0
i=startBlock
while i <= endBlock:
if mode.v == 1:
print 'Blanking block %i '%(i)
else:
sys.stdout.write(".")
sys.stdout.flush()
don.erase_block(i)
if mode.version < 5:
don.wait_on_busy()
don.parse_status() #do this after programming all but uneaven ending
i=i+1
if mode.v == 0:
print " "
print "Test SUCCESSFUL!"
sys.exit()
except IOError:
print "IO Error on file open"
sys.exit()
if mode.e == 1: # perform dongle test
#Erase Dongle
print "Erasing all"
don.write_command(0x0060) # 0x0098
don.write_command(0x00D0) # 0x0098
if mode.version < 5:
don.wait_on_busy()
don.parse_status()
endBlock = 31
startBlock = 0
i=startBlock
while i <= endBlock:
if mode.v == 1:
print 'Erasing block %i '%(i)
else:
sys.stdout.write(".")
sys.stdout.flush()
don.erase_block(i)
if mode.version < 5:
don.wait_on_busy()
don.parse_status() #do this after programming all but uneaven ending
i=i+1
if mode.v == 0: # add CRTL return to dots
print ""
if mode.version >= 5:
print "Waiting for buffers to empty"
don.wait_on_busy()
don.parse_status() #do this after programming all but uneaven ending
print "Erase done."
if mode.l == 1: # perform dongle test
#Erase Dongle
print "Status Loop test"
i=1024
startTime = time.clock()
while i > 0:
sys.stdout.write(".")
sys.stdout.flush()
don.wait_on_busy()
don.parse_status() #do this after programming all but uneaven ending
i=i-1
if sys.platform=='win32':
endTime = (time.clock()-startTime)/1024.0
print "\nSystem round delay is %4f ms"%(endTime*1000.0)
sys.stdout.flush()
##########################################################
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -