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 36

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

powered by: WebSVN 2.1.0

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