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

Subversion Repositories usb_dongle_fpga

[/] [usb_dongle_fpga/] [trunk/] [sw/] [dongle.py] - Blame information for rev 46

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

Line No. Rev Author Line
1 2 nuubik
#! /usr/bin/python
2 17 nuubik
# -*- coding: ISO-8859-1 -*-
3
 
4 2 nuubik
##########################################################################
5
# LPC Dongle programming software 
6
#
7 23 nuubik
# Copyright (C) 2008 Artec Design
8 2 nuubik
# 
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:   LPC Dongle programming software 
26
# Name:      dongle.py
27
# Purpose:   Executable command line tool 
28
#
29 23 nuubik
# Author:    Jüri Toomessoo <jyrit@artecdesign.ee>
30
# Copyright: (c) 2008 by Artec Design
31 2 nuubik
# Licence:   LGPL
32
#
33
# Created:   06 Oct. 2006
34
# History:   12 oct. 2006  Version 1.0 released
35 8 nuubik
#            22 Feb. 2007  Test options added to test PCB board
36 23 nuubik
#            10 Nov. 2007  Added open retry code to dongle
37 17 nuubik
#            14 Nov. 2007  Moved dongle spesific code to class Dongle from USPP
38
#                          USPP is allmost standard now (standard USPP would work)
39
#                          Artec USPP has serial open retry
40
#            14 Nov. 2007  Improved help. 
41 23 nuubik
#            10 Mar. 2008  Forced code to hw flow control settings made linux 1 byte read to 2 bytes
42
#                          as dongle never reads 1 byte at the time
43 44 nuubik
#            18 Apr. 2008  Added file size boundary check on write to see if remaining size from
44
#                          given offset fits the file size
45 46 nuubik
 
46
#            24 Apr. 2008  Mac OS X support by Stefan Reinauer <stepan@coresystems.de>
47 2 nuubik
#-------------------------------------------------------------------------
48
 
49
import os
50
import sys
51
import string
52
import time
53 23 nuubik
import struct
54 2 nuubik
from sets import *
55
from struct import *
56
 
57 23 nuubik
#### inline of artec FTDI spesific Uspp code ###################################################
58
 
59
##########################################################################
60
# USPP Library (Universal Serial Port Python Library)
61
#
62
# Copyright (C) 2006 Isaac Barona <ibarona@gmail.com>
63
# 
64
# This library is free software; you can redistribute it and/or
65
# modify it under the terms of the GNU Lesser General Public
66
# License as published by the Free Software Foundation; either
67
# version 2.1 of the License, or (at your option) any later version.
68
# 
69
# This library is distributed in the hope that it will be useful,
70
# but WITHOUT ANY WARRANTY; without even the implied warranty of
71
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
72
# Lesser General Public License for more details.
73
 
74
# You should have received a copy of the GNU Lesser General Public
75
# License along with this library; if not, write to the Free Software
76
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
77
##########################################################################
78
 
79
#-------------------------------------------------------------------------
80
# Project:   USPP Library (Universal Serial Port Python Library)
81
# Name:      uspp.py
82
# Purpose:   Main module. Imports the correct module for the platform
83
#            in which it is running.
84
#
85
# Author:    Isaac Barona Martinez <ibarona@gmail.com>
86
# Contributors:
87
#            Damien Géranton <dgeranton@voila.fr>
88
#            Douglas Jones <dfj23@drexel.edu>
89
#            J.Grauheding <juergen.grauheding@a-city.de>
90
#            J.Toomessoo jyrit@artecdesign.ee
91
#
92
# Copyright: (c) 2006 by Isaac Barona Martinez
93
# Licence:   LGPL
94
#
95
# Created:   26 June 2001
96
# History:
97
#            05/08/2001: Release version 0.1.
98
#            24/02/2006: Final version 1.0.
99
#            10/11/2007: Added open retry code to dongle
100
#                        by Jyri Toomessoo jyrit@artecdesign.ee
101
#            14/11/2007: Moved dongle spesific code to class Dongle from USPP
102
#                        USPP is allmost standard now (standard USPP would work)
103
#                        Artec USPP has serial open retry
104
#                        by Jyri Toomessoo jyrit@artecdesign.ee
105
#            10/03/2008: Forced code to hw flow control settings made linux 1 byte read to 2 bytes
106
#                        as dongle never reads 1 byte at the time
107
#                        by Jyri Toomessoo jyrit@artecdesign.ee
108
#            10/03/2008: Copose single infile bundle for FTDI USB serial 1.2
109
#                        this is nonuniversal modification of the code to suite the need of Artec Design Dongle
110
#                        by Jyri Toomessoo jyrit@artecdesign.ee
111
#-------------------------------------------------------------------------
112
 
113
 
114
drv_ok = 0
115
if sys.platform=='win32':
116
    print "Windows platform detected:"
117
    if drv_ok == 0:
118
        try:
119
            from win32file import *
120
            from win32event import *
121
            import win32con
122
            import exceptions
123
 
124
            print "Using VCP FTDI driver"
125
        except ImportError,SerialPortException:
126
            print "Python for winiows extensions for COM not found"
127
            print "(see https://sourceforge.net/projects/pywin32/)"
128
            print "Could not find any usable support for FTDI chip in python"
129
            print "Try installing python support from one of the links."
130
            sys.exit()
131
elif sys.platform=='linux2':
132
    from termios import *
133
    import fcntl
134
    import exceptions
135
    import array
136
    print "Linux platform detected:"
137 46 nuubik
elif sys.platform=='darwin':
138
    from termios import *
139
    import fcntl
140
    import exceptions
141
    import array
142
    print "Mac OS X platform detected:"
143 23 nuubik
else:
144
    sys.exit('Sorry, no implementation for this platform yet')
145
 
146
 
147
 
148
class SerialPortException(exceptions.Exception):
149
    """Exception raise in the SerialPort methods"""
150
    def __init__(self, args=None):
151
        self.args=args
152
    def __str__(self):
153
        return repr(self.args)
154
 
155
 
156
if sys.platform=='win32':
157
  class SerialPortWin:
158
    BaudRatesDic={110: CBR_110,
159
                  300: CBR_300,
160
                  600: CBR_600,
161
                  1200: CBR_1200,
162
                  2400: CBR_2400,
163
                  4800: CBR_4800,
164
                  9600: CBR_9600,
165
                  19200: CBR_19200,
166
                  38400: CBR_38400,
167
                  57600: CBR_57600,
168
                  115200: CBR_115200,
169
                  128000: CBR_128000,
170
                  256000: CBR_256000
171
                  }
172
 
173
    def __init__(self, dev, timeout=None, speed=115200, mode='232', params=None):
174
        self.__devName, self.__timeout, self.__speed=dev, timeout, speed
175
        self.__mode=mode
176
        self.__params=params
177
        self.__speed = 0
178
        self.__reopen = 0
179
        while 1:
180
            try:
181
                self.__handle=CreateFile (dev,
182
                win32con.GENERIC_READ|win32con.GENERIC_WRITE,
183
                0, # exclusive access
184
                None, # no security
185
                win32con.OPEN_EXISTING,
186
                win32con.FILE_ATTRIBUTE_NORMAL,
187
                None)
188
                break
189
 
190
            except:
191
                n=0
192
                while (n < 2000000):
193
                    n += 1;
194
                self.__reopen = self.__reopen + 1
195
            if self.__reopen > 32:
196
                print "Port does not exist..."
197
                raise SerialPortException('Port does not exist...')
198
                break
199
                #sys.exit()
200
        self.__configure()
201
 
202
    def __del__(self):
203
        if self.__speed:
204
            try:
205
                CloseHandle(self.__handle)
206
            except:
207
                raise SerialPortException('Unable to close port')
208
 
209
 
210
 
211
 
212
    def __configure(self):
213
        if not self.__speed:
214
            self.__speed=115200
215
        # Tell the port we want a notification on each char
216
        SetCommMask(self.__handle, EV_RXCHAR)
217
        # Setup a 4k buffer
218
        SetupComm(self.__handle, 4096, 4096)
219
        # Remove anything that was there
220
        PurgeComm(self.__handle, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|
221
                  PURGE_RXCLEAR)
222
        if self.__timeout==None:
223
            timeouts= 0, 0, 0, 0, 0
224
        elif self.__timeout==0:
225
            timeouts = win32con.MAXDWORD, 0, 0, 0, 1000
226
        else:
227
            timeouts= self.__timeout, 0, self.__timeout, 0 , 1000
228
        SetCommTimeouts(self.__handle, timeouts)
229
 
230
        # Setup the connection info
231
        dcb=GetCommState(self.__handle)
232
        dcb.BaudRate=SerialPortWin.BaudRatesDic[self.__speed]
233
        if not self.__params:
234
            dcb.ByteSize=8
235
            dcb.Parity=NOPARITY
236
            dcb.StopBits=ONESTOPBIT
237
            dcb.fRtsControl=RTS_CONTROL_ENABLE
238
            dcb.fOutxCtsFlow=1
239
        else:
240
            dcb.ByteSize, dcb.Parity, dcb.StopBits=self.__params
241
        SetCommState(self.__handle, dcb)
242
 
243
 
244
    def fileno(self):
245
        return self.__handle
246
 
247
 
248
    def read(self, num=1):
249
        (Br, buff) = ReadFile(self.__handle, num)
250
        if len(buff)<>num and self.__timeout!=0: # Time-out  
251
            print 'Expected %i bytes but got %i before timeout'%(num,len(buff))
252
            raise SerialPortException('Timeout')
253
        else:
254
            return buff
255
 
256
 
257
    def readline(self):
258
        s = ''
259
        while not '\n' in s:
260
            s = s+SerialPortWin.read(self,1)
261
 
262
        return s
263
 
264
 
265
    def write(self, s):
266
        """Write the string s to the serial port"""
267
        errCode = 0
268
        overlapped=OVERLAPPED()
269
        overlapped.hEvent=CreateEvent(None, 0,0, None)
270
        (errCode, bytesWritten) = WriteFile(self.__handle, s,overlapped)
271
        # Wait for the write to complete
272
        WaitForSingleObject(overlapped.hEvent, INFINITE)
273
        return bytesWritten
274
 
275
    def inWaiting(self):
276
        """Returns the number of bytes waiting to be read"""
277
        flags, comstat = ClearCommError(self.__handle)
278
        return comstat.cbInQue
279
 
280
    def flush(self):
281
        """Discards all bytes from the output or input buffer"""
282
        PurgeComm(self.__handle, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|
283
                  PURGE_RXCLEAR)
284
 
285
 
286
 
287 46 nuubik
if sys.platform=='linux2':
288 23 nuubik
  class SerialPortLin:
289
    """Encapsulate methods for accesing to a serial port."""
290
 
291
    BaudRatesDic={
292
        110: B110,
293
        300: B300,
294
        600: B600,
295
        1200: B1200,
296
        2400: B2400,
297
        4800: B4800,
298
        9600: B9600,
299
        19200: B19200,
300
        38400: B38400,
301
        57600: B57600,
302
        115200: B115200,
303
        230400: B230400
304
        }
305
    buf = array.array('h', '\000'*4)
306
 
307
    def __init__(self, dev, timeout=None, speed=115200, mode='232', params=None):
308
        self.__devName, self.__timeout, self.__speed=dev, timeout, speed
309
        self.__mode=mode
310
        self.__params=params
311
        self.__speed = 0
312
        self.__reopen = 0
313
        while 1:
314
            try:
315
                self.__handle=os.open(dev, os.O_RDWR)
316
                break
317
 
318
            except:
319
                n=0
320
                while (n < 2000000):
321
                    n += 1;
322
                self.__reopen = self.__reopen + 1
323
            if self.__reopen > 32:
324
                print "Port does not exist..."
325
                raise SerialPortException('Port does not exist...')
326
                break
327
 
328
        self.__configure()
329
 
330
    def __del__(self):
331
        if self.__speed:
332
            #tcsetattr(self.__handle, TCSANOW, self.__oldmode)
333
            pass
334
            try:
335
                pass
336
                os.close(self.__handle)
337
            except IOError:
338
                raise SerialPortException('Unable to close port')
339
 
340
 
341
    def __configure(self):
342
        if not self.__speed:
343
            self.__speed=115200
344
 
345
        # Save the initial port configuration
346
        self.__oldmode=tcgetattr(self.__handle)
347
        if not self.__params:
348
            # print "Create linux params for serialport..."
349
            # self.__params is a list of attributes of the file descriptor
350
            # self.__handle as follows:
351
            # [c_iflag, c_oflag, c_cflag, c_lflag, c_ispeed, c_ospeed, cc]
352
            # where cc is a list of the tty special characters.
353
            self.__params=[]
354
            # c_iflag
355
            self.__params.append(IGNPAR)
356
            # c_oflag
357
            self.__params.append(0)
358
            # c_cflag
359
            self.__params.append(CS8|CREAD|CRTSCTS)
360
            # c_lflag
361
            self.__params.append(0)
362
            # c_ispeed
363
            self.__params.append(SerialPortLin.BaudRatesDic[self.__speed])
364
            # c_ospeed
365
            self.__params.append(SerialPortLin.BaudRatesDic[self.__speed])
366
            cc=[0]*NCCS
367
        if self.__timeout==None:
368
            # A reading is only complete when VMIN characters have
369
            # been received (blocking reading)
370
            cc[VMIN]=1
371
            cc[VTIME]=0
372
        elif self.__timeout==0:
373
            cc[VMIN]=0
374
            cc[VTIME]=0
375
        else:
376
            cc[VMIN]=0
377
            cc[VTIME]=self.__timeout #/100
378
        self.__params.append(cc)               # c_cc
379
 
380
        tcsetattr(self.__handle, TCSANOW, self.__params)
381
 
382
 
383
    def fileno(self):
384
        return self.__handle
385
 
386
 
387
    def __read1(self):
388
        tryCnt = 0
389
        byte = ""
390
        while(len(byte)==0 and tryCnt<10):
391
            tryCnt+=1
392
            byte = os.read(self.__handle, 2)
393
        if len(byte)==0 and self.__timeout!=0: # Time-out
394
            print 'Time out cnt was %i'%(tryCnt)
395
            print 'Expected 1 byte but got %i before timeout'%(len(byte))
396
            sys.stdout.flush()
397
            raise SerialPortException('Timeout')
398
        else:
399
            return byte
400
 
401
 
402
    def read(self, num=1):
403
        s=''
404
        for i in range(num/2):
405
            s=s+SerialPortLin.__read1(self)
406
        return s
407
 
408
 
409
    def readline(self):
410
 
411
        s = ''
412
        while not '\n' in s:
413
            s = s+SerialPortLin.__read1(self)
414
 
415
        return s
416
 
417
 
418
    def write(self, s):
419
        """Write the string s to the serial port"""
420
        return os.write(self.__handle, s)
421
 
422
    def inWaiting(self):
423
        """Returns the number of bytes waiting to be read"""
424
        data = struct.pack("L", 0)
425
        data=fcntl.ioctl(self.__handle, TIOCINQ, data)
426
        return struct.unpack("L", data)[0]
427
 
428
    def outWaiting(self):
429
        """Returns the number of bytes waiting to be write
430
        mod. by J.Grauheding
431
        result needs some finetunning
432
        """
433
        rbuf=fcntl.ioctl(self.__handle, TIOCOUTQ, self.buf)
434
        return rbuf
435
 
436
 
437
    def flush(self):
438
        """Discards all bytes from the output or input buffer"""
439
        tcflush(self.__handle, TCIOFLUSH)
440
 
441
 
442 46 nuubik
if sys.platform=='darwin':
443
  class SerialPortOSX:
444
    """Encapsulate methods for accesing to a serial port."""
445 23 nuubik
 
446 46 nuubik
    BaudRatesDic={
447
        110: B110,
448
        300: B300,
449
        600: B600,
450
        1200: B1200,
451
        2400: B2400,
452
        4800: B4800,
453
        9600: B9600,
454
        19200: B19200,
455
        38400: B38400,
456
        57600: B57600,
457
        115200: B115200,
458
        230400: B230400
459
        }
460
    buf = array.array('h', '\000'*4)
461
 
462
    def __init__(self, dev, timeout=None, speed=115200, mode='232', params=None):
463
        self.__devName, self.__timeout, self.__speed=dev, timeout, speed
464
        self.__mode=mode
465
        self.__params=params
466
        self.__speed = 0
467
        self.__reopen = 0
468
        while 1:
469
            try:
470
                self.__handle=os.open(dev, os.O_RDWR)
471
                break
472
 
473
            except:
474
                n=0
475
                while (n < 2000000):
476
                    n += 1;
477
                self.__reopen = self.__reopen + 1
478
            if self.__reopen > 32:
479
                print "Port does not exist..."
480
                raise SerialPortException('Port does not exist...')
481
                break
482
 
483
        self.__configure()
484
 
485
    def __del__(self):
486
        if self.__speed:
487
            #tcsetattr(self.__handle, TCSANOW, self.__oldmode)
488
            pass
489
            try:
490
                pass
491
                #os.close(self.__handle)
492
            except IOError:
493
                raise SerialPortException('Unable to close port')
494
 
495
 
496
    def __configure(self):
497
        if not self.__speed:
498
            self.__speed=115200
499
 
500
        # Save the initial port configuration
501
        self.__oldmode=tcgetattr(self.__handle)
502
        if not self.__params:
503
            # print "Create MacOSX params for serialport..."
504
            # self.__params is a list of attributes of the file descriptor
505
            # self.__handle as follows:
506
            # [c_iflag, c_oflag, c_cflag, c_lflag, c_ispeed, c_ospeed, cc]
507
            # where cc is a list of the tty special characters.
508
            self.__params=[]
509
            # c_iflag
510
            self.__params.append(IGNPAR)
511
            # c_oflag
512
            self.__params.append(0)
513
            # c_cflag
514
            self.__params.append(CS8|CREAD|CRTSCTS)
515
            # c_lflag
516
            self.__params.append(0)
517
            # c_ispeed
518
            self.__params.append(SerialPortOSX.BaudRatesDic[self.__speed])
519
            # c_ospeed
520
            self.__params.append(SerialPortOSX.BaudRatesDic[self.__speed])
521
            cc=[0]*NCCS
522
        if self.__timeout==None:
523
            # A reading is only complete when VMIN characters have
524
            # been received (blocking reading)
525
            cc[VMIN]=1
526
            cc[VTIME]=0
527
        elif self.__timeout==0:
528
            cc[VMIN]=0
529
            cc[VTIME]=0
530
        else:
531
            cc[VMIN]=0
532
            cc[VTIME]=self.__timeout #/100
533
        self.__params.append(cc)               # c_cc
534
 
535
        tcsetattr(self.__handle, TCSANOW, self.__params)
536
 
537
 
538
    def fileno(self):
539
        return self.__handle
540
 
541
 
542
    def __read1(self):
543
        tryCnt = 0
544
        byte = ""
545
        while(len(byte)==0 and tryCnt<10):
546
            tryCnt+=1
547
            byte = os.read(self.__handle, 2)
548
        if len(byte)==0 and self.__timeout!=0: # Time-out
549
            print 'Time out cnt was %i'%(tryCnt)
550
            print 'Expected 1 byte but got %i before timeout'%(len(byte))
551
            sys.stdout.flush()
552
            raise SerialPortException('Timeout')
553
        else:
554
            return byte
555
 
556
 
557
    def read(self, num=1):
558
        s=''
559
        for i in range(num/2):
560
            s=s+SerialPortOSX.__read1(self)
561
        return s
562
 
563
 
564
    def readline(self):
565
 
566
        s = ''
567
        while not '\n' in s:
568
            s = s+SerialPortOSX.__read1(self)
569
 
570
        return s
571
 
572
 
573
    def write(self, s):
574
        """Write the string s to the serial port"""
575
        return os.write(self.__handle, s)
576
 
577
    def inWaiting(self):
578
        """Returns the number of bytes waiting to be read"""
579
        data = struct.pack("L", 0)
580
        data=fcntl.ioctl(self.__handle, FIONREAD, data)
581
        return struct.unpack("L", data)[0]
582
 
583
    def outWaiting(self):
584
        """Returns the number of bytes waiting to be write
585
        mod. by J.Grauheding
586
        result needs some finetunning
587
        """
588
        rbuf=fcntl.ioctl(self.__handle, FIONWRITE, self.buf)
589
        return rbuf
590
 
591
 
592
    def flush(self):
593
        """Discards all bytes from the output or input buffer"""
594
        tcflush(self.__handle, TCIOFLUSH)
595
 
596
 
597
 
598 23 nuubik
#### end inline of artec FTDI spesific Uspp code ###############################################
599
 
600
 
601
#### Dongle code starts here  ##################################################################
602
 
603
 
604 2 nuubik
#### global funcs ####
605
def usage(s):
606 46 nuubik
    print "Artec USB Dongle programming utility ver. 2.6"
607 17 nuubik
    print "Usage:"
608
    print "Write file      : ",s," [-vq] -c <name> <file> <offset>"
609
    print "Readback file   : ",s," [-vq] -c <name> [-vq] -r <offset> <length> <file>"
610 2 nuubik
    print "Options:"
611 17 nuubik
    print " <file> <offset> When file and offset are given file will be written to dongle"
612
    print "        file:    File name to be written to dongle"
613
    print "        offset:  Specifies data writing starting point in bytes to 4M window"
614
    print "                 For ThinCan boot code the offset = 4M - filesize. To write"
615
    print "                 256K file the offset must be 3840K"
616
    print " "
617
    print " -c <name>       Indicate port name where the USB Serial Device is"
618
    print "        name:    COM port name in Windows or Linux Examples: COM3,/dev/ttyS3"
619
    print "                 See Device Manager in windows for USB Serial Port number"
620
    print " "
621
    print " -v              Enable verbose mode. Displays more progress information"
622
    print " "
623
    print " -q              Perform flash query to see if dongle flash is responding"
624
    print " "
625
    print " -r <offset> <length> <file>  Readback data. Available window size is 4MB"
626 23 nuubik
    print "        offset:  Offset byte addres inside 4MB window. Example: 1M"
627
    print "                 use M for MegaBytes, K for KiloBytes, none for bytes"
628
    print "                 use 0x prefix to indicate hexademical number format"
629 17 nuubik
    print "        length:  Amount in bytes to read starting from offset. Example: 1M"
630
    print "                 use M for MegaBytes, K for KiloBytes, none for bytes"
631
    print "        file:    Filename where data will be written"
632
    print " "
633
    print " -e              Erase device. Erases Full 4 MegaBytes"
634 8 nuubik
    print "Board test options: "
635 17 nuubik
    print " -t              Marching one and zero test. Device must be empty"
636
    print "                 To test dongle erase the flash with command -e"
637
    print "                 Enables dongle memory tests to be executed by user"
638
    print " "
639 29 nuubik
    print " -b              Leave flash blank after test. Used with option -t"
640 23 nuubik
    print " -l              Fast poll loop test. Does poll loop 1024 times"
641
    print "                 used to stress test connection"
642 8 nuubik
    print ""
643 2 nuubik
    print "Examples:"
644
    print ""
645 17 nuubik
    print " ",s," -c COM3 loader.bin 0                       "
646
    print " ",s," -c /dev/ttyS3 boot.bin 3840K"
647
    print " ",s," -c COM3 -r 0x3C0000 256K flashcontent.bin"
648 46 nuubik
    print " ",s," -c /dev/cu.usbserial-003011FD -v (Mac OS X)"
649 2 nuubik
######################
650
 
651
 
652
class DongleMode:
653
    def __init__(self):
654
        self.v = 0
655
        self.f = 0
656
        self.d = 0
657
        self.q = 0
658
        self.r = 0
659 8 nuubik
        self.t = 0
660
        self.e = 0
661 23 nuubik
        self.b = 0
662
        self.l = 0
663 2 nuubik
        self.filename=""
664
        self.portname=""
665
        self.address=-1
666
        self.offset=-1
667
        self.length=-1
668 23 nuubik
        self.version=4
669 2 nuubik
 
670
    def convParamStr(self,param):
671
        mult = 1
672
        value = 0
673
        str = param
674
        if str.find("K")>-1:
675
            mult = 1024
676
            str=str.strip("K")
677
        if str.find("M")>-1:
678
            mult = 1024*1024
679
            str=str.strip("M")
680
        try:
681
            if str.find("x")>-1:
682
                value = int(str,0)*mult  #conver hex string to int
683
            else:
684
                value = int(str)*mult  #conver demical string to int
685
        except ValueError:
686
            print "Bad parameter format given for: ",param
687
 
688
        return value
689
 
690
 
691
 
692
 
693
class Dongle:
694
    def __init__(self,name, baud, timeout):  #time out in millis 1000 = 1s baud like 9600, 57600
695 23 nuubik
        self.mode = 0
696 2 nuubik
        try:
697 23 nuubik
            if sys.platform=='win32':
698
                self.tty = SerialPortWin(name,timeout, baud)
699 46 nuubik
            elif sys.platform=='linux2':
700 23 nuubik
                self.tty = SerialPortLin(name,timeout, baud)
701 46 nuubik
            elif sys.platform=='darwin':
702
                self.tty = SerialPortOSX(name,timeout, baud)
703 23 nuubik
 
704 17 nuubik
        except SerialPortException , e:
705
            print "Unable to open port " + name
706 2 nuubik
            sys.exit();
707 9 nuubik
 
708
    def testReturn(self,byteCount):
709
        i=0
710
        while don.tty.inWaiting()<byteCount:
711
            i=i+1
712
            if i==10000*byteCount:
713
                break
714
        if i==10000*byteCount:
715
            return 0
716 23 nuubik
        j=don.tty.inWaiting()
717
        #print "Tested in waiting %i needed %i"%(j,byteCount)
718
        return j  ## ret two bytes            
719 9 nuubik
 
720 2 nuubik
    def getReturn(self,byteCount):
721
        i=0
722 23 nuubik
        #while don.tty.inWaiting()<byteCount:
723
        #    i=i+1
724
        #    time.sleep(0.1)
725
        #    if i==100*byteCount:
726
        #        print "Dongle not communicating"
727
        #        #print "Read in waiting %i needed %i was %i"%(i,byteCount,don.tty.inWaiting())
728
        #        sys.exit()
729
        #        break
730
 
731
        #i=don.tty.inWaiting()
732
        #print "Read in waiting %i needed %i was %i"%(i,byteCount,don.tty.inWaiting())
733
        buf = don.tty.read(byteCount)
734
        #print "Got bytes =%i "%(len(buf))
735
        return buf  ## ret two bytes
736 9 nuubik
 
737 2 nuubik
 
738
    def write_command(self,command):
739
        lsb = command&0xff
740
        msb = (command>>8)&0xff
741 17 nuubik
        self.write_2bytes(msb,lsb)
742
 
743
    def write_2bytes(self, msb,lsb):
744
        """Write one word MSB,LSB to the serial port MSB first"""
745
        s = pack('BB', msb, lsb)
746 23 nuubik
        ret = self.tty.write(s)
747
        if(ret<len(s)):
748
            print 'write_2byte: Wrote less then needed %i bytes from %i'%(ret,length(s))
749 17 nuubik
        # Wait for the write to complete
750
        #WaitForSingleObject(overlapped.hEvent, INFINITE)               
751 2 nuubik
 
752
    def get_address_buf(self,address):  #set word address
753
        lsbyte = address&0xff
754
        byte = (address>>8)&0xff
755
        msbyte = (address>>16)&0xff
756
        buffer = ""
757
        buffer += chr(lsbyte)
758
        buffer += chr(0xA0)
759
        buffer +=  chr(byte)
760
        buffer +=  chr(0xA1)
761
        buffer +=  chr(msbyte)
762
        buffer +=  chr(0xA2)
763
        evaluate = (address>>24)
764
        if evaluate != 0:
765
            print "Addressign fault. Too large address passed"
766
            sys.exit()
767
        return buffer
768
 
769
 
770
    def set_address(self,address):  #set word address
771
        lsbyte = address&0xff
772
        byte = (address>>8)&0xff
773
        msbyte = (address>>16)&0xff
774
        evaluate = (address>>24)
775
        if evaluate != 0:
776
            print "Addressign fault. Too large address passed"
777
            sys.exit()
778 17 nuubik
        self.write_2bytes(lsbyte,0xA0)            #set internal address to dongle
779
        self.write_2bytes(byte,0xA1)            #set internal address to dongle
780
        self.write_2bytes(msbyte,0xA2)            #send query command
781 2 nuubik
 
782
    def read_data(self,wordCount,address):
783
        command = 0
784
        byteCount = wordCount<<1  #calc byte count
785
        if wordCount>0 :
786
            command = (command|wordCount)<<8;
787
            command = command|0xCD
788
            self.set_address(address)    # send read address
789
            self.write_command(command)  # send get data command
790
            return self.getReturn(byteCount)
791
        else:
792
            print "Word count can't be under 1"
793
            sys.exit()
794 23 nuubik
 
795 2 nuubik
 
796 23 nuubik
    def issue_blk_read(self):
797
        command = 0
798
        wordCount = 0
799
        byteCount = wordCount<<1  #calc byte count
800
        command = (command|wordCount)<<8;
801
        command = command|0xCD
802
        self.write_command(command)  # send get data command
803
 
804
 
805
 
806
 
807 2 nuubik
    def read_status(self):
808
        don.write_command(0x0070) # 0x0098 //clear status
809
        command = 0
810
        wordCount= 1  #calc byte count
811
        byteCount = wordCount<<1
812
        command = (command|wordCount)<<8;
813
        command = command|0xCD
814
        self.write_command(command)  # send get data command
815
        return self.getReturn(byteCount)
816
 
817
 
818
    def get_block_no(self,address):
819
        return address >> 16 # 16 bit mode block is 64Kwords
820
 
821
    def wait_on_busy(self):
822
        exit=0
823
        while exit==0:
824
            buf=self.read_status()
825
            statReg = ord(buf[0])  #8 bit reg
826
            if statReg>>7 == 1:
827
                exit=1
828
 
829
    def parse_status(self):  # use only after wait on busy commad to get result of the operation
830
        exit = 0
831
        buf=self.read_status()
832
        statReg = ord(buf[0])  #8 bit reg
833
        if (statReg>>5)&1 == 1:
834
            print "Block erase suspended"
835
            exit = 1
836
        if (statReg>>4)&3 == 3:
837
            print "Error in command order"  #if bits 4 and 5 are set then 
838
            exit = 1
839
        if (statReg>>4)&3 == 1:
840
            print "Error in setting lock bit"
841
            exit = 1
842
        if (statReg>>3)&1 == 1:
843
            print "Low Programming Voltage Detected, Operation Aborted"
844
            exit = 1
845
        if (statReg>>2)&1 == 1:
846
            print "Programming suspended"
847
            exit = 1
848
        if (statReg>>1)&1 == 1:
849
            print "Block lock bit detected"
850
            exit = 1
851
        if exit == 1:
852
            sys.exit()
853
 
854
    def erase_block(self,blockNo):
855
        blockAddress = blockNo << 16
856
        command = 0x0020
857
        self.set_address(blockAddress)
858
        self.write_command(command)  #issue block erase
859
        command = 0x00D0
860
        self.write_command(command)  #issue block erase confirm
861 23 nuubik
        #self.wait_on_busy()
862
        #self.parse_status()
863 2 nuubik
 
864
    def buffer_write(self,wordCount,startAddress,buffer):
865
        # to speed up buffer writing compose all commands into one buffer
866
        # instead of multiple single writes this is needed as the FTDI chip
867
        # round lag is amazingly large with VCOM drivers
868
        #u = len(buffer)
869
        if len(buffer)<32:            #don't ever make unaligned writes
870
            i=len(buffer)
871
            while len(buffer)<32:
872
                buffer += "\xff"
873
        adrBuf = self.get_address_buf(startAddress)   #6 bytes total
874
        cmd_e8=""  #8 bytes total
875
        cmd_e8+= chr(16)   #make it always 16 wordCount
876
        cmd_e8+= chr(0xE8)
877
        cmd_wcnt=""  #10 bytes total
878
        cmd_wcnt+= chr(0x00)
879
        cmd_wcnt+= chr(16-1)
880
        cmd_buf=""  #12 bytes total
881
        cmd_buf+= chr(0x00)
882
        cmd_buf+= chr(0xD0)
883
        wr_buffer_cmd = adrBuf + cmd_e8 + cmd_wcnt + buffer + cmd_buf   #44 bytes total
884 17 nuubik
        self.write_buf_cmd(wr_buffer_cmd)
885 23 nuubik
 
886
        if self.mode.version <5:
887
            n = 0
888
            if sys.platform=='win32':
889
                while (n < 1024):
890
                    n += 1;
891 46 nuubik
            elif sys.platform=='linux2' or sys.platform=='darwin':
892 23 nuubik
                #Linux FTDI VCP driver is way faster and needs longer grace time than windows driver
893
                while (n < 1024*8):
894
                    n += 1;
895 17 nuubik
 
896
    def write_buf_cmd(self, buffer):
897
        """Write one word MSB,LSB to the serial port MSB first"""
898
        a=0
899
        s=""
900
        if (len(buffer) < 44):  # if buffer is shorter than expected then pad with read array mode commands
901
            i=0
902
            while i<len(buffer):
903
                print '0x%02x'%(ord(buffer[i]))
904
                i+=1
905
            while(a < len(buffer)):
906
                if a < 10:
907
                    s= pack('2c', buffer[a], buffer[a+1])
908
                    self.tty.write(s)
909
                elif a < len(buffer)-2:
910
                    s= pack('2c', buffer[a+1], buffer[a])
911
                    self.tty.write(s)
912
                elif  len(buffer)==2:
913
                    s=pack('2c', buffer[a], buffer[a+1])
914
                    self.tty.write(s)
915
                else:
916
                     s=pack('2c', buffer[a], chr(0xFF))
917
                     self.tty.write(s)
918
                a+=2
919
        else:
920
            #first 10 bytes are in correct order + 32 data bytes are in wrong order and + 2 confirm bytes are in correct order
921
            s=pack('44c',
922
            buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5], buffer[6], buffer[7],
923
            buffer[8], buffer[9], buffer[11], buffer[10], buffer[13], buffer[12], buffer[15], buffer[14],
924
            buffer[17], buffer[16], buffer[19], buffer[18], buffer[21], buffer[20], buffer[23], buffer[22],
925
            buffer[25], buffer[24], buffer[27], buffer[26], buffer[29], buffer[28], buffer[31], buffer[30],
926
            buffer[33], buffer[32], buffer[35], buffer[34], buffer[37], buffer[36], buffer[39], buffer[38],
927
            buffer[41], buffer[40], buffer[42], buffer[43]
928
            )
929 23 nuubik
 
930
            ret = self.tty.write(s)
931
 
932 2 nuubik
 
933
 
934
################## Main program #########################
935
 
936
 
937
last_ops = 0
938
mode = DongleMode()
939
# PARSE ARGUMENTS 
940
for arg in sys.argv:
941
    if len(sys.argv) == 1: # if no arguments display help
942 8 nuubik
       #usage(sys.argv[0])
943
       usage("dongle.py")
944 2 nuubik
       sys.exit()
945
    if arg in ("-h","--help","/help","/h"):
946 8 nuubik
        #usage(sys.argv[0])
947
        usage("dongle.py")
948 2 nuubik
        sys.exit()
949
    if arg in ("-c"):
950
        last_ops = sys.argv.index(arg) + 1  #if remains last set of options from here start ordered strings
951
        i = sys.argv.index(arg)
952
        print "Opening port: "+sys.argv[i+1]
953
        mode.portname = sys.argv[i+1]   # next element after -c open port for usage
954
    if arg[0]=="-" and arg[1]!="c": # if other opptions
955
        # parse all options in this
956
        last_ops = sys.argv.index(arg)  #if remains last set of options from here start ordered strings
957
        ops = arg[1:]# get all besides the - sign
958
        for op in ops:
959
            if op=="q":
960
                mode.q = 1
961
            if op=="v":
962
                mode.v = 1
963
            if op=="f":
964
                mode.f = 1
965
            if op=="d":
966
                mode.d = 1
967
            if op=="r":
968 8 nuubik
                mode.r = 1
969
            if op=="t":
970
                mode.t = 1
971
            if op=="e":
972
                mode.e = 1
973
            if op=="b":
974 23 nuubik
                mode.b = 1
975
            if op=="l":
976
                mode.l = 1
977 2 nuubik
    else:
978
        i = sys.argv.index(arg)
979
        if i ==  last_ops + 1:
980
            if mode.r==1:
981
                mode.offset=mode.convParamStr(arg)
982
            else:
983
                mode.filename=arg
984
        if i ==  last_ops + 2:
985
            if mode.r==1:
986
                mode.length=mode.convParamStr(arg)
987
            else:
988
                mode.address=mode.convParamStr(arg)
989
 
990
        if i ==  last_ops + 3:
991
            if mode.r==1:
992
                mode.filename=arg
993
            else:
994
                print "Too many parameters provided"
995
                sys.exit()
996
        if i >  last_ops + 3:
997
             print "Too many parameters provided"
998
             sys.exit()
999
 
1000
# END PARSE ARGUMENTS             
1001
 
1002
if mode.portname=="":
1003
    print "No port name given see -h for help"
1004
    sys.exit()
1005
else:
1006
    # test PC speed to find sutable delay for linux driver
1007
    # to get 250 us 
1008
    mytime = time.clock()
1009
    n = 0
1010
    while (n < 100000):
1011
        n += 1;
1012
    k10Time = time.clock() - mytime   # time per 10000 while cycles
1013
    wait = k10Time/100000.0     # time per while cycle
1014
    wait = (0.00025/wait) * 1.20   # count for 250us + safe margin
1015
    # ok done
1016 9 nuubik
    reopened = 0
1017
 
1018 23 nuubik
 
1019
    if sys.platform=='win32':
1020
        don  = Dongle(mode.portname,256000,6000)
1021
    elif sys.platform=='linux2':
1022
        don  = Dongle(mode.portname,230400,6000)
1023
        #don.tty.cts()
1024 46 nuubik
    elif sys.platform=='darwin':
1025
        don  = Dongle(mode.portname,230400,6000)
1026
        #don.tty.cts()
1027 23 nuubik
    else:
1028
        sys.exit('Sorry, no implementation for this platform yet')
1029
 
1030
 
1031 9 nuubik
    don.tty.wait = wait
1032
    while 1:
1033
        don.write_command(0x0050) # 0x0098
1034
        don.write_command(0x00C5)            #send dongle check internal command
1035
        don_ret=don.testReturn(2)
1036
        if don_ret==2:
1037
            break
1038
        if reopened == 3:
1039
             print 'Dongle connected, but does not communicate'
1040
             sys.exit()
1041
        reopened = reopened + 1
1042
        # reopen and do new cycle
1043 23 nuubik
        if sys.platform=='win32':
1044
            don  = Dongle(mode.portname,256000,6000)
1045
        elif sys.platform=='linux2':
1046
            don  = Dongle(mode.portname,230400,6000)
1047
            #self.tty.cts()
1048 46 nuubik
        elif sys.platform=='darwin':
1049
            don  = Dongle(mode.portname,230400,6000)
1050
            #self.tty.cts()
1051 23 nuubik
        else:
1052
            sys.exit('Sorry, no implementation for this platform yet')
1053 9 nuubik
        don.tty.wait = wait
1054
 
1055 2 nuubik
    buf=don.getReturn(2)  # two bytes expected to this command
1056
    if ord(buf[1])==0x32 and  ord(buf[0])==0x10:
1057
        print "Dongle OK"
1058
    else:
1059
        print 'Dongle returned on open: %02x %02x '%(ord(buf[1]), ord(buf[0]))
1060 23 nuubik
    don.write_command(0x01C5)            #try getting dongle HW ver (works since 05 before that returns 0x3210)
1061
    buf=don.getReturn(2)  # two bytes expected to this command
1062
    if ord(buf[1])==0x86 and  ord(buf[0])>0x04:
1063
        mode.version = ord(buf[0])
1064
        don.mode = mode
1065
        print 'Dongle HW version code is  %02x %02x'%(ord(buf[1]), ord(buf[0]))
1066
    else:
1067
        don.mode = mode
1068
        print 'Dongle HW version code is smaller than 05 some features have been improved on'
1069
        print 'HW code and Quartus FPGA binary file are available at:'
1070
        print 'http://www.opencores.org/projects.cgi/web/usb_dongle_fpga/overview'
1071 29 nuubik
        print 'Programming is possible with Altera Quartus WE and BYTEBLASTER II cable or'
1072
        print 'compatible clone like X-Blaster http://www.customcircuitsolutions.com/cable.html'
1073 2 nuubik
 
1074
if mode.q == 1:   # perform a query from dongle
1075 9 nuubik
 
1076
    buf=don.read_data(4,0x0)  # word count and word address
1077 2 nuubik
    don.write_command(0x0050) # 0x0098
1078
    don.write_command(0x0098) # 0x0098
1079
    buf=don.read_data(3,0x000010)  # word count and word address
1080
    if ord(buf[0])==0x51 and  ord(buf[2])==0x52 and  ord(buf[4])==0x59:
1081
        buf=don.read_data(2,0x000000)  # word count and word address
1082 23 nuubik
        print 'Query  OK, Flash Factory Code is: 0x%02x device: 0x%02x '%(ord(buf[0]),ord(buf[2]))
1083 2 nuubik
        buf=don.read_data(2,0x000002)
1084
        print 'lock bit is 0x%02x 0x%02x'%(ord(buf[0]),ord(buf[1]))
1085
    else:
1086 23 nuubik
        print "Got bad Flash query data:"
1087 2 nuubik
        print 'Query address 0x10 = 0x%02x%02x '%(ord(buf[1]),ord(buf[0]))
1088 9 nuubik
        print 'Query address 0x12 = 0x%02x%02x '%(ord(buf[3]),ord(buf[2]))
1089
        print 'Query address 0x14 = 0x%02x%02x '%(ord(buf[5]),ord(buf[4]))
1090 2 nuubik
        print "Read byte count:",len(buf)
1091
 
1092
    don.write_command(0x00FF) # 0x0098
1093 9 nuubik
    buf=don.read_data(4,0xff57c0>>1)  # word count and word address
1094
 
1095 2 nuubik
    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]) )
1096
 
1097
 
1098
 
1099
if mode.filename!="" and mode.address!=-1:
1100
    #Calculate number of blocks and start of blocks
1101
    size = 0
1102
    mode.address = mode.address>>1  #make word address
1103
    try:
1104
        f=open(mode.filename,"rb")
1105
        f.seek(0,2) #seek to end
1106
        size = f.tell()
1107
        f.seek(0) #seek to start
1108
        print 'File size %iK '%(size/1024)
1109
        f.close()
1110
    except IOError:
1111 42 nuubik
         print "IO Error on file open. File missing or no premission to open."
1112 2 nuubik
         sys.exit()
1113
    #clear blockLock bits
1114
    don.write_command(0x0060) # 0x0098
1115
    don.write_command(0x00D0) # 0x0098
1116 23 nuubik
    if mode.version < 5:
1117
        don.wait_on_busy()
1118
        don.parse_status()
1119 2 nuubik
    wordSize = (size+ (size&1))>> 1    # round byte count up and make word address
1120
    endBlock = don.get_block_no(mode.address+wordSize - 1)
1121
    startBlock = don.get_block_no(mode.address)
1122 44 nuubik
    if endBlock >= 32:
1123 42 nuubik
        print "Given file does not fit into remaining space. File size is %i KB"%(size/1024)
1124
        print "Space left from given offset is %i KB"%((4*1024*1024-mode.address*2)/1024)
1125
        sys.exit()
1126 2 nuubik
    i=startBlock
1127 9 nuubik
    print 'Erasing from block %i to %i '%(i,endBlock)
1128 2 nuubik
    while i <= endBlock:
1129 9 nuubik
        if mode.v == 1:
1130
            print 'Erasing block %i '%(i)
1131
        else:
1132
            sys.stdout.write(".")
1133
            sys.stdout.flush()
1134 2 nuubik
        don.erase_block(i)
1135 23 nuubik
        if mode.version < 5:
1136
            don.wait_on_busy()
1137
            don.parse_status()   #do this after programming all but uneaven ending
1138 2 nuubik
        i=i+1
1139 9 nuubik
    if mode.v == 0:
1140
        print " "
1141 2 nuubik
    #don.write_command(0x00FF) # 0x0098
1142
    #buf=don.read_data(4,0x000000)  # word count and word address     
1143
    #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]) )
1144
 
1145
    f=open(mode.filename,"rb")
1146
    f.seek(0) #seek to start
1147
    address= mode.address
1148
    #don.set_address(address)
1149 9 nuubik
    print 'Writing %iK'%(size/1024)
1150 2 nuubik
    while 1:
1151 9 nuubik
        if (address/(1024*64) != (address-16)/(1024*64)) and address != mode.address:  # get bytes from words if 512
1152
            if mode.v == 1:
1153
                print 'Progress: %iK of %iK at 0x%06x'%((address-mode.address)/512,size/1024,address)
1154
            else:
1155
                sys.stdout.write(".")
1156
                sys.stdout.flush()
1157 2 nuubik
        buf = f.read(32)  #16 words is maximum write here bytes are read
1158
        if len(buf)==32:
1159
            don.buffer_write(16,address,buf)
1160
            address = address + 16
1161
        elif len(buf)>0:
1162
            don.parse_status()   #do this after programming all but uneaven ending
1163
            print "Doing an unaligned write..."
1164
            length = len(buf)
1165
            length = (length + (length&1))>> 1   #round up to get even word count
1166
            buf = buf+"\xff"   #pad just in case rounding took place
1167
            don.buffer_write(len,address,buf)
1168
            address = address + 16     #inc word address
1169
            break
1170
        else:
1171
            break
1172 9 nuubik
    if mode.v == 0:
1173
        print " "
1174 23 nuubik
    if mode.version >= 5:
1175
        print "Waiting for buffers to empty"
1176
        don.wait_on_busy()
1177
        don.parse_status()   #do this after programming all but uneaven ending        
1178 2 nuubik
    print "Write DONE!"
1179
    don.parse_status()   #do this after programming all but uneaven ending
1180
    f.close()
1181
 
1182
if mode.r == 1:   # perform a readback
1183
    if mode.offset!=-1 and mode.length!=-1 and mode.filename!="":
1184 23 nuubik
        if mode.version >= 5:
1185
            ##################### from hw ver 5 readback code ##################################################
1186
            blockCount = (mode.length>>17)+1 #read this many 64K word blocks
1187
            mode.offset=mode.offset>>1    #make word offset
1188
            lastLength = mode.length&0x0001FFFF
1189
            mode.length= mode.length>>1   #make word length
1190
            if mode.length < 512:
1191
                print 'Reading %i bytes in single block '%(lastLength)
1192
            else:
1193
                print 'Reading %iK in %i blocks '%(mode.length/512,blockCount)
1194 2 nuubik
            don.write_command(0x00FF) #  put flash to data read mode
1195 23 nuubik
            try:
1196
                f=open(mode.filename,"wb")  #if this fails no point in reading as there is nowhere to write
1197
                address = mode.offset    # set word address
1198
                don.set_address(address)
1199
                i=0
1200
                while (i<blockCount):
1201
                    don.issue_blk_read()  # request 64K words from current address
1202
                    buf=don.getReturn(65536*2) #Read all words
1203
                    if (i==blockCount-1):  #last block
1204
                        f.write(buf[:lastLength])
1205
                    else:
1206
                        f.write(buf) ## must tuncate the buffer
1207 9 nuubik
                    if mode.v == 1:
1208 23 nuubik
                        print 'Got block %i'%(i+1)
1209 9 nuubik
                    else:
1210
                        sys.stdout.write(".")
1211
                        sys.stdout.flush()
1212 23 nuubik
                    i+=1
1213
                f.close()
1214
            except IOError:
1215
                print "IO Error on file open"
1216
                sys.exit()
1217
            ##################### end from hw ver 5 readback code  ############################################ 
1218
        else:
1219
            ##################### before hw ver 5 readback code ###############################################
1220
            mode.offset=mode.offset>>1    #make word offset
1221
            mode.length= mode.length>>1   #make word length
1222
            print 'Reading %iK'%(mode.length/512)
1223
            try:
1224
                f=open(mode.filename,"wb")
1225
                don.write_command(0x00FF) #  put flash to data read mode
1226
                address = mode.offset    # set word address
1227
                while 1:
1228
                    if address/(1024*32) != (address-128)/(1024*32):  # get K bytes from words if 512
1229
                        if mode.v == 1:
1230
                            print 'Progress: %iK of %iK'%((address-mode.offset)/512,mode.length/512)
1231
                        else:
1232
                            sys.stdout.write(".")
1233
                            sys.stdout.flush()
1234
                    buf=don.read_data(128,address)  # word count and byte address read 64 words to speed up
1235
                    f.write(buf)
1236
                    #print "from address:",address<<1," ", len(buf)
1237
                    if address+128 >= (mode.offset + mode.length):  # 2+64 estimates the end to end in right place
1238
                        break
1239
                    address = address + 128    #this is word address
1240
                f.close()
1241
                if mode.v == 0:
1242
                    print " "
1243
                print "Readback done!"
1244
            except IOError:
1245
                print "IO Error on file open"
1246
                sys.exit()
1247
       ##################### end before hw ver 5 readback code  ################################################ 
1248 2 nuubik
    else:
1249
       print "Some of readback parameters missing..."
1250
       print mode.offset,mode.length, mode.filename
1251
       sys.exit()
1252 8 nuubik
 
1253
if mode.t == 1:   # perform dongle test
1254
        print "Dongle TEST"
1255
        if mode.e == 1:
1256
            #Erase Dongle
1257 9 nuubik
            print "Erasing"
1258 8 nuubik
            don.write_command(0x0060) # 0x0098
1259
            don.write_command(0x00D0) # 0x0098
1260
            don.wait_on_busy()
1261
            don.parse_status()
1262
            endBlock = 31
1263
            startBlock = 0
1264
            i=startBlock
1265
            while i <= endBlock:
1266 9 nuubik
                if mode.v == 1:
1267
                    print 'Erasing block %i '%(i)
1268
                else:
1269
                     sys.stdout.write(".")
1270
                     sys.stdout.flush()
1271 8 nuubik
                don.erase_block(i)
1272
                don.wait_on_busy()
1273
                don.parse_status()   #do this after programming all but uneaven ending
1274 9 nuubik
                i=i+1
1275
            if mode.v == 0: # add CRTL return to dots
1276
                print ""
1277 8 nuubik
        #Do marching one test on data and address
1278
        mode.length= 0   #make word length
1279
        try:
1280
            #Marching one test
1281
            #---------------------------------------------------------------------------
1282
            address = 0x100000    # set word address
1283
            data = 0x100000
1284
            while mode.length<20: # last address to test 0x20 0000  
1285
                buf1=pack('BBBB', (0x000000FF&data),(0x0000FF00&data)>>8 ,(0x00FF0000&data)>>16 ,(0xFF0000&data)>>24 )
1286
                don.buffer_write(2,address,buf1)
1287
                don.parse_status()   #do this after programming all but uneaven ending
1288
                don.write_command(0x00FF) #  put flash to data read mode   
1289
                buf2=don.read_data(2,address)  # word count and byte address read 64 words to speed up
1290
                if buf1 != buf2:
1291
                    print 'IN  %02x %02x %02x %02x '%(ord(buf1[3]), ord(buf1[2]),ord(buf1[1]), ord(buf1[0]))
1292
                    print 'OUT %02x %02x %02x %02x '%(ord(buf2[3]), ord(buf2[2]),ord(buf2[1]), ord(buf2[0]))
1293
                    print "Test FAIL!!!!!"
1294
                    sys.exit()
1295
                address = address >> 1
1296
                if address == 0x2:
1297
                    address = address >> 1  # 0x2 is written and will return zero on read as write new write will fail
1298
                data = data >> 1
1299
                mode.length =  mode.length + 1
1300
                buf2=don.read_data(1,0)  #read first byte
1301
                if ord(buf2[0]) != 0xFF:
1302
                    print "Test FAIL (At least one address line const. 0)!!!!!"
1303 9 nuubik
                    sys.exit()
1304 8 nuubik
            #-----------------------------------------------------------------------
1305
            #Marching zero test
1306
            address = 0xFFEFFFFF    # set word address
1307
            data = 0x100000
1308
            while mode.length<18: # last address to test 0x20 0000  
1309
                buf1=pack('BBBB', (0x000000FF&data),(0x0000FF00&data)>>8 ,(0x00FF0000&data)>>16 ,(0xFF0000&data)>>24 )
1310
                don.buffer_write(2,address,buf1)
1311
                don.parse_status()   #do this after programming all but uneaven ending
1312
                don.write_command(0x00FF) #  put flash to data read mode   
1313
                buf2=don.read_data(2,address&0x1FFFFF)  # word count and byte address read 64 words to speed up
1314
                if buf1 != buf2:
1315
                    print 'IN  %02x %02x %02x %02x '%(ord(buf1[3]), ord(buf1[2]),ord(buf1[1]), ord(buf1[0]))
1316
                    print 'OUT %02x %02x %02x %02x '%(ord(buf2[3]), ord(buf2[2]),ord(buf2[1]), ord(buf2[0]))
1317
                    print "Test FAIL!!!!!"
1318
                    sys.exit()
1319
                address = (address >> 1)|0xFF000000
1320
                data = data >> 1
1321
                mode.length =  mode.length + 1
1322
                buf2=don.read_data(1,0x1FFFFF)  #read first byte
1323
                if ord(buf2[0]) != 0xFF:
1324
                    print "Test FAIL (At least two address lines bonded)!!!!!"
1325 9 nuubik
                    sys.exit()
1326 8 nuubik
            if mode.b == 1:
1327
                #Erase Dongle
1328 9 nuubik
                print "Erasing"
1329 8 nuubik
                don.write_command(0x0060) # 0x0098
1330
                don.write_command(0x00D0) # 0x0098
1331
                don.wait_on_busy()
1332
                don.parse_status()
1333
                endBlock = 31
1334
                startBlock = 0
1335
                i=startBlock
1336
                while i <= endBlock:
1337 9 nuubik
                    if mode.v == 1:
1338
                        print 'Blanking block %i '%(i)
1339
                    else:
1340
                        sys.stdout.write(".")
1341
                        sys.stdout.flush()
1342 8 nuubik
                    don.erase_block(i)
1343 23 nuubik
                    if mode.version < 5:
1344
                        don.wait_on_busy()
1345
                        don.parse_status()   #do this after programming all but uneaven ending
1346 9 nuubik
                    i=i+1
1347
                if mode.v == 0:
1348
                    print " "
1349 8 nuubik
            print "Test SUCCESSFUL!"
1350 9 nuubik
            sys.exit()
1351 8 nuubik
        except IOError:
1352
            print "IO Error on file open"
1353
            sys.exit()
1354
 
1355 9 nuubik
if mode.e == 1:   # perform dongle test
1356
            #Erase Dongle
1357
            print "Erasing all"
1358
            don.write_command(0x0060) # 0x0098
1359
            don.write_command(0x00D0) # 0x0098
1360 23 nuubik
            if mode.version < 5:
1361
                don.wait_on_busy()
1362
                don.parse_status()
1363 9 nuubik
            endBlock = 31
1364
            startBlock = 0
1365
            i=startBlock
1366
            while i <= endBlock:
1367
                if mode.v == 1:
1368
                    print 'Erasing block %i '%(i)
1369
                else:
1370
                     sys.stdout.write(".")
1371
                     sys.stdout.flush()
1372
                don.erase_block(i)
1373 23 nuubik
                if mode.version < 5:
1374
                    don.wait_on_busy()
1375
                    don.parse_status()   #do this after programming all but uneaven ending
1376 9 nuubik
                i=i+1
1377
            if mode.v == 0: # add CRTL return to dots
1378
                print ""
1379 23 nuubik
            if mode.version >= 5:
1380
                print "Waiting for buffers to empty"
1381
                don.wait_on_busy()
1382
                don.parse_status()   #do this after programming all but uneaven ending
1383 9 nuubik
            print "Erase done."
1384 23 nuubik
 
1385
if mode.l == 1:   # perform dongle test            
1386
            #Erase Dongle
1387
            print "Status Loop test"
1388
            i=1024
1389
            startTime = time.clock()
1390
            while i > 0:
1391
                sys.stdout.write(".")
1392
                sys.stdout.flush()
1393
                don.wait_on_busy()
1394
                don.parse_status()   #do this after programming all but uneaven ending
1395
                i=i-1
1396
            if sys.platform=='win32':
1397
                endTime = (time.clock()-startTime)/1024.0
1398
                print "\nSystem round delay is %4f ms"%(endTime*1000.0)
1399
            sys.stdout.flush()
1400 2 nuubik
##########################################################

powered by: WebSVN 2.1.0

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