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

Subversion Repositories artec_dongle_ii_fpga

[/] [artec_dongle_ii_fpga/] [trunk/] [update/] [update.py] - Blame information for rev 10

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 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.1 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 or"
52
    print "http://fpgaguy.110mb.com/"
53
    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
        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
 
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
time.sleep(0.5)
504
 

powered by: WebSVN 2.1.0

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