OpenCores
URL https://opencores.org/ocsvn/usb_dongle_fpga/usb_dongle_fpga/trunk

Subversion Repositories usb_dongle_fpga

[/] [usb_dongle_fpga/] [trunk/] [update/] [update.py] - Blame information for rev 53

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 36 nuubik
#! /usr/bin/python
2
# -*- coding: ISO-8859-1 -*-
3
 
4
##########################################################################
5
# Programming utility for Altera EPCS memory on USB Dongle PCB
6
#
7
# Copyright (C) 2008 Artec Design
8
# 
9
# This library is free software; you can redistribute it and/or
10
# modify it under the terms of the GNU Lesser General Public
11
# License as published by the Free Software Foundation; either
12
# version 2.1 of the License, or (at your option) any later version.
13
# 
14
# This software is distributed in the hope that it will be useful,
15
# but WITHOUT ANY WARRANTY; without even the implied warranty of
16
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17
# Lesser General Public License for more details.
18
 
19
# You should have received a copy of the GNU Lesser General Public
20
# License along with this library; if not, write to the Free Software
21
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
22
##########################################################################
23
 
24
#-------------------------------------------------------------------------
25
# Project:   Programming utility for Altera EPCS memory on USB Dongle PCB
26
# Name:      update.py
27
# Purpose:   Executable command line tool 
28
#
29
# Author:    Jüri Toomessoo <jyrit@artecdesign.ee>
30
# Copyright: (c) 2008 by Artec Design
31
# Licence:   LGPL
32
#
33
# Created:   12 Mar. 2008
34
# History:   12 Mar. 2008  Version 0.2 released
35
#-------------------------------------------------------------------------
36
 
37
import os
38
import sys
39
import string
40
import time
41
 
42
 
43
 
44
#### EPCS code starts here  ##################################################################
45
 
46
 
47
#### global funcs ####
48
def usage(s):
49 39 nuubik
    print "Artec's Altera EPCS programming utility ver. 0.2.1 for USB Dongle"
50 36 nuubik
    print "Use with Altera ByteBlaster II programmer or compatible clone on LPT1"
51 39 nuubik
    print "like X-Blaster http://www.customcircuitsolutions.com/cable.html or"
52
    print "http://fpgaguy.110mb.com/"
53 36 nuubik
    print "Usage:"
54
    print "Query           : ",s," -q"
55
    print "Write file      : ",s," [-v] <file>"
56
    print "Readback file   : ",s," [-v] -r <file>"
57
    print "Options:"
58
    print " -v              Enable verbose mode. Displays more progress information"
59
    print " -q              Perform EPCS and ByteBlaster II query to see if all is ok"
60
    print ""
61
    print "Examples:"
62
    print ""
63
    print " ",s," dongle_syn.rpd "
64
    print " ",s," -r epcs_content.rpd "
65
######################
66
 
67
 
68
class DeviceMode:
69
    def __init__(self):
70
        self.v = 0
71
        self.f = 0
72
        self.d = 0
73
        self.q = 0
74
        self.r = 0
75
        self.t = 0
76
        self.e = 0
77
        self.b = 0
78
        self.l = 0
79
        self.filename=""
80
        self.portname=""
81
        self.address=-1
82
        self.offset=-1
83
        self.length=-1
84
        self.version=4
85
 
86
    def convParamStr(self,param):
87
        mult = 1
88
        value = 0
89
        str = param
90
        if str.find("K")>-1:
91
            mult = 1024
92
            str=str.strip("K")
93
        if str.find("M")>-1:
94
            mult = 1024*1024
95
            str=str.strip("M")
96
        try:
97
            if str.find("x")>-1:
98
                value = int(str,0)*mult  #conver hex string to int
99
            else:
100
                value = int(str)*mult  #conver demical string to int
101
        except ValueError:
102
            print "Bad parameter format given for: ",param
103
 
104
        return value
105
 
106
 
107
 
108
 
109
class EPCSDevice:
110
 
111
    def __init__(self):
112
        self._data = 0xFF
113
        self.mode = 0                  #commands are bit flipped
114
        self.CMD_WRITE_ENABLE = 0x60   #0x06
115
        self.CMD_WRITE_DISABLE= 0x20   #0x04
116
        self.CMD_READ_STATUS=0xA0      #0x05
117
        self.CMD_READ_BYTES=0xC0       #0x03
118
        self.CMD_READ_ID=0xD5          #0xAB
119
        self.CMD_WRITE_STATUS=0x80     #0x01
120
        self.CMD_WRITE_BYTES=0x40      #0x02
121
        self.CMD_ERASE_BULK=0xE3       #0xC7
122
        self.CMD_ERASE_SECTOR=0x1B     #0xD8
123
        if sys.platform=='win32':
124
            try:
125
                import parallel
126
            except ImportError:
127
                print "Can't find pyparallel module"
128
                print "pyparallel is available at: "
129
                print "http://pyserial.sourceforge.net/pyparallel.html"
130
                print "Supports Windows NT/2k/XP trough giveio.sys"
131
                sys.exit()
132
            self.pport = parallel.Parallel()
133
 
134
        else:
135
            try:
136
                import parallel
137
            except ImportError:
138
                print "Can't find pyparallel module"
139
                print "pyparallel is available at: "
140
                print "http://pyserial.sourceforge.net/pyparallel.html"
141
                print "Supports Linux trough ppdev driver"
142
                sys.exit()
143
            self.pport = parallel.Parallel()
144
 
145
    def open(self):
146
        i=0
147
        self.pport.setAutoFeed(1) #enable BB II tristate buffers to drive
148
        #self.pport.setDataDir(0xFF)  #enable out mode on pport
149
        self.pport.setData(0x10)  # set pport D4 this is looped back to ACK when tri's are enabled
150
        if self.pport.getInAcknowledge():
151
            i=i+1
152
        self.pport.setData(0x00)  # set pport D4 this is looped back to ACK when tri's are enabled
153
        if not self.pport.getInAcknowledge():
154
            i=i+1
155
        if i==2:
156
            print "Found ByteBlaster II compatible programmer"
157
        else:
158
            print "Can't find ByteBlaster II on parallel port"
159
            sys.exit()
160
        self.pport.setData(0xFF)
161
        self._data = 0xFF
162
 
163
 
164
    def close(self):
165 39 nuubik
        epcs.pport.setData(0xFF)
166
        epcs.pport.setAutoFeed(1) #disable BB II tristate buffers to drive
167
        epcs.clearPPDataBit(3)  #enable Cyclon chip
168
        epcs.clearPPDataBit(2)  #enable Cyclon chip     
169 36 nuubik
 
170
    def setPPDataBit(self,bit_no):
171
        self._data = self._data|(1<<bit_no)
172
        self.pport.setData(self._data)
173
        #print "set bit %i setData(0x%2x)"%(bit_no,self._data)
174
        #time.sleep(0.0001)
175
 
176
 
177
 
178
    def clearPPDataBit(self,bit_no):
179
        self._data = self._data&(~(1<<bit_no))
180
        self.pport.setData(self._data)
181
        #print "clr bit %i setData(0x%2x)"%(bit_no,self._data)
182
        #time.sleep(0.0001)
183
 
184
    def setASDI(self,bit):
185
        bit_cleared = self._data&(~(1<<6))   # deal with bit 6 pport D6
186
        bit_cleared = bit_cleared|(bit<<6)
187
        self._data = bit_cleared
188
        self.pport.setData(self._data)
189
        #print "ast bit %i setData(0x%2x)"%(bit,self._data)
190
        #time.sleep(0.0001)
191
 
192
    def startCycle(self):
193
       self.clearPPDataBit(2)    # pport D2 is nCS so bit 2 must go low
194
       #time.sleep(0.0001)
195
 
196
    def endCycle(self):
197
        self.setPPDataBit(2)    # pport D2 is nCS so bit 2 must go low
198
        #time.sleep(0.0001)
199
 
200
    def clockCycle(self):
201
        self.clearPPDataBit(0)  # make falling edge
202
        #time.sleep(0.0001)
203
        self.setPPDataBit(0)    # make rising edge
204
        #time.sleep(0.0001)
205
 
206
    def writeCommand(self,command):
207
        i=0
208
        #print "-------------------"
209
        while i<8:
210
            self.setASDI(command&0x01)
211
            #print "write cmd bit %i"%(command&0x00000001)
212
            self.clockCycle()
213
            command = command >> 1
214
            i+=1
215
        #print "-------------------"
216
 
217
    def writeFlippedByte(self,byte):
218
        #ok lets do bit reversal in a byte
219
        #it would be faster with a look up table (even with autogenerated one) FIXME
220
        i=0
221
        while i<8:
222
            self.setASDI(byte&0x01)
223
            self.clockCycle()
224
            byte = byte >> 1
225
            i+=1
226
 
227
    def writeByte(self,byte):
228
        #ok lets do bit reversal in a byte
229
        #it would be faster with a look up table (even with autogenerated one) FIXME
230
        etyb = ((byte&0x01)<<7)|((byte&0x02)<<5)|((byte&0x04)<<3)|((byte&0x08)<<1)|((byte&0x10)>>1)|((byte&0x20)>>3)|((byte&0x40)>>5)|((byte&0x80)>>7)
231
        i=0
232
        while i<8:
233
            self.setASDI(etyb&0x01)
234
            self.clockCycle()
235
            etyb = etyb >> 1
236
            i+=1
237
 
238
    def writeAddress(self,address):
239
        byte = (address&0x00FF0000)>>16
240
        self.writeByte(byte) #this is used to write byte of address
241
        byte = (address&0x0000FF00)>>8
242
        self.writeByte(byte)
243
        byte = (address&0x000000FF)
244
        self.writeByte(byte)
245
 
246
 
247
    def readByte(self):
248
        i=0
249
        byte = 0
250
        #print "-------------------"
251
        while i<8:
252
            byte = byte << 1
253
            self.clearPPDataBit(0)  # make falling edge for read
254
            if self.pport.getInSelected():
255
                byte=byte|0x01
256
            self.setPPDataBit(0)  # make rising edge for read
257
            i+=1
258
        #print "-------------------"
259
        return byte
260
 
261
    #########################  EPCS command calls   #############################
262
    def getDeviceID(self):
263
        self.startCycle()
264
        self.writeCommand(self.CMD_READ_ID)
265
        self.writeCommand(0x00) # dummy write
266
        self.writeCommand(0x00) # dummy write
267
        self.writeCommand(0x00) # dummy write
268
        byte = self.readByte()
269
        self.endCycle()
270
        return byte
271
 
272
    def setWriteEnable(self):
273
        self.startCycle()
274
        self.writeCommand(self.CMD_WRITE_ENABLE)
275
        self.endCycle()
276
 
277
    def setWriteDisable(self):
278
        self.startCycle()
279
        self.writeCommand(self.CMD_WRITE_DISABLE)
280
        self.endCycle()
281
 
282
    def getStatusReg(self):
283
        self.startCycle()
284
        self.writeCommand(self.CMD_READ_STATUS)
285
        byte = self.readByte()
286
        self.endCycle()
287
        return byte
288
 
289
    def readBytes(self,address,count):
290
        buffer = ""
291
        i = 0
292
        self.startCycle()
293
        self.writeCommand(self.CMD_READ_BYTES)
294
        self.writeAddress(address)
295
        while(i<count):
296
            byte = self.readByte()
297
            #print "Reading %2x"%(byte)
298
            buffer = buffer + chr(byte)  #this can continue endlessly if needed the address is auto INC'ed and is freerunning
299
            i+=1
300
        self.endCycle()
301
        return buffer
302
 
303
    def readFlippedBytes(self,address,count):
304
        buffer = ""
305
        i = 0
306
        self.startCycle()
307
        self.writeCommand(self.CMD_READ_BYTES)
308
        self.writeAddress(address)
309
        while(i<count):
310
            byte = self.readByte()
311
            etyb = ((byte&0x01)<<7)|((byte&0x02)<<5)|((byte&0x04)<<3)|((byte&0x08)<<1)|((byte&0x10)>>1)|((byte&0x20)>>3)|((byte&0x40)>>5)|((byte&0x80)>>7)
312
            #print "Reading %2x"%(byte)
313
            buffer = buffer + chr(etyb)  #this can continue endlessly if needed the address is auto INC'ed and is freerunning
314
            i+=1
315
        self.endCycle()
316
        return buffer
317
 
318
    def writeBytes(self,address,buffer):  #256 is maximum and is physical page limit of EPCS devices
319
        count = len(buffer)
320
        i = 0
321
        self.setWriteEnable()  #will be autoreset after this
322
        self.startCycle()
323
        self.writeCommand(self.CMD_WRITE_BYTES)
324
        self.writeAddress(address)
325
        while(i<count):
326
            #print "Writing %2x"%(ord(buffer[i]))
327
            self.writeByte(ord(buffer[i]))  #used also to write a data byte
328
            i+=1
329
        self.endCycle()
330
        time.sleep(0.0001)  #wait untill write compleate, wite time is in order of millis
331
        while(self.getStatusReg()&0x01==1):
332
            time.sleep(0.00001)
333
 
334
    def writeFlippedBytes(self,address,buffer):  #256 is maximum and is physical page limit of EPCS devices (Altera RPD file is allready byte flipped)
335
        #This is used to programm altera byte flipped programming files
336
        count = len(buffer)
337
        i = 0
338
        self.setWriteEnable()  #will be autoreset after this
339
        self.startCycle()
340
        self.writeCommand(self.CMD_WRITE_BYTES)
341
        self.writeAddress(address)
342
        while(i<count):
343
            #print "Writing %2x"%(ord(buffer[i]))
344
            self.writeFlippedByte(ord(buffer[i]))  #used also to write a data byte
345
            i+=1
346
        self.endCycle()
347
        time.sleep(0.0001)  #wait untill write compleate, wite time is in order of millis
348
        while(self.getStatusReg()&0x01==1):
349
            time.sleep(0.00001)
350
 
351
    def eraseBulk(self):
352
        self.setWriteEnable()  #will be autoreset after this
353
        self.startCycle()
354
        self.writeCommand(self.CMD_ERASE_BULK)
355
        self.endCycle()
356
        time.sleep(3)  #wait untill write compleate, wite time is in order of secs
357
        while(self.getStatusReg()&0x01==1):
358
            time.sleep(0.1)
359
 
360
 
361
    def eraseSector(self,address):
362
        self.setWriteEnable()  #will be autoreset after this
363
        self.startCycle()
364
        self.writeCommand(self.CMD_ERASE_SECTOR)
365
        self.writeAddress(address)
366
        self.endCycle()
367
        time.sleep(1)  #wait untill write compleate, wite time is in order of secs
368
        while(self.getStatusReg()&0x01==1):
369
            time.sleep(0.2)
370
    #########################  end EPCS command calls   #########################
371
 
372
 
373
 
374
################## Main program #########################
375
 
376
 
377
last_ops = 0
378
mode = DeviceMode()
379
# PARSE ARGUMENTS 
380
for arg in sys.argv:
381
    if len(sys.argv) == 1: # if no arguments display help
382
       #usage(sys.argv[0])
383
       usage("update.py")
384
       sys.exit()
385
    if arg in ("-h","--help","/help","/h"):
386
        #usage(sys.argv[0])
387
        usage("update.py")
388
        sys.exit()
389
 
390
    if arg[0]=="-": # if options
391
        # parse all options in this
392
        last_ops = sys.argv.index(arg)  #if remains last set of options from here start ordered strings
393
        ops = arg[1:]# get all besides the - sign
394
        for op in ops:
395
            if op=="q":
396
                mode.q = 1
397
            if op=="v":
398
                mode.v = 1
399
            if op=="r":
400
                mode.r = 1
401
            if op=="e":
402
                mode.e = 1
403
    else:
404
        i = sys.argv.index(arg)
405
        if i ==  last_ops + 1:
406
            mode.filename=arg
407
        if i >=  last_ops + 2:
408
            print "Too many parameters provided"
409
            sys.exit()
410
 
411
############## END PARSE ARGUMENTS   ###############################################33          
412
 
413
 
414
epcs = EPCSDevice()
415
epcs.open()
416
if epcs.pport.getInError():
417
    print "No Voltage source detected"
418
else:
419
    print "Voltage source OK"
420
 
421
byte = epcs.getDeviceID()
422
if byte == 0x10:
423
    print "EPCS1 Configuration device found"
424
    if mode.q == 1:
425
        print "EPCS Silicon ID = 0x%2x"%(byte)
426
        sys.exit()   # if q then exit
427
elif not byte == 0xFF:
428
    print "Not supported device found"
429
    if mode.q == 1:
430
        print "Silicon ID = 0x%2x"%(byte)
431
    sys.exit()
432
else:
433
    if not epcs.pport.getInError():
434
        print "No device attached to cable"
435
        if mode.q == 1:
436
            print "Got 0x%2x for ID "%(byte)
437
    epcs.close()
438
    sys.exit()
439
 
440
if mode.e == 1:
441
    print "Erasing EPCS device"
442
    epcs.eraseBulk()
443
    print "Done"
444
 
445
if mode.filename!="" and mode.r==0:
446
    print "Erasing EPCS device"
447
    epcs.eraseBulk()
448
    print "Done"
449
    size = 0
450
    mode.address = 0
451
    try:
452
        f=open(mode.filename,"rb")
453
        f.seek(0,2) #seek to end
454
        size = f.tell()
455
        f.seek(0) #seek to start
456
        print 'File size %iK '%(size/1024)
457
        f.close()
458
    except IOError:
459
         print "IO Error on file open"
460
         sys.exit()
461
    #all seems in order so lest start     
462
    f=open(mode.filename,"rb")
463
    f.seek(0) #seek to start
464
    address = mode.address
465
    print 'Writing %iK'%(size/1024)
466
    while 1:
467
        if (address/(1024*4) != (address-16)/(1024*4)) and address != mode.address:  # get bytes from words if 512
468
            if mode.v == 1:
469
                print 'Progress: %iK of %iK at 0x%06x'%((address-mode.address)/1024,size/1024,address)
470
            else:
471
                sys.stdout.write(".")
472
                sys.stdout.flush()
473
        buf = f.read(256)  #we can write 256 bytes at a time
474
        if len(buf)==256:
475
            epcs.writeFlippedBytes(address,buf)
476
            address = address + 256  #we use byte address
477
        elif len(buf)>0:
478
            epcs.writeFlippedBytes(address,buf) #write last bytes
479
            break
480
        else:
481
            break
482
    if mode.v == 0:
483
        print " "
484
    print "Write DONE!"
485
    f.close()
486
elif mode.filename!="":   # then read flag must be up
487
    size = 0x20000   #byte count of EPCS1 device
488
    try:
489
        f=open(mode.filename,"wb")  #if this fails no point in reading as there is nowhere to write
490
        address = 0    # set word address
491
        buf=""
492
        print "Start readback"
493
        buf=epcs.readFlippedBytes(address,size)
494
        print "Read done"
495
        f.write(buf)
496
        f.close()
497
        print "Done"
498
    except IOError:
499
        print "IO Error on file open"
500
        sys.exit()
501
 
502
epcs.close()
503 39 nuubik
time.sleep(0.5)
504 36 nuubik
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.