URL
https://opencores.org/ocsvn/usb_dongle_fpga/usb_dongle_fpga/trunk
Subversion Repositories usb_dongle_fpga
Compare Revisions
- This comparison shows the changes necessary to convert path
/usb_dongle_fpga/tags/version_1_5/sw
- from Rev 45 to Rev 53
- ↔ Reverse comparison
Rev 45 → Rev 53
/dongle.py
0,0 → 1,1228
#! /usr/bin/python |
# -*- coding: ISO-8859-1 -*- |
|
########################################################################## |
# LPC Dongle programming software |
# |
# Copyright (C) 2008 Artec Design |
# |
# This library is free software; you can redistribute it and/or |
# modify it under the terms of the GNU Lesser General Public |
# License as published by the Free Software Foundation; either |
# version 2.1 of the License, or (at your option) any later version. |
# |
# This software is distributed in the hope that it will be useful, |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
# Lesser General Public License for more details. |
|
# You should have received a copy of the GNU Lesser General Public |
# License along with this library; if not, write to the Free Software |
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
########################################################################## |
|
#------------------------------------------------------------------------- |
# Project: LPC Dongle programming software |
# Name: dongle.py |
# Purpose: Executable command line tool |
# |
|
# Copyright: (c) 2008 by Artec Design |
# Licence: LGPL |
# |
# Created: 06 Oct. 2006 |
# History: 12 oct. 2006 Version 1.0 released |
# 22 Feb. 2007 Test options added to test PCB board |
# 10 Nov. 2007 Added open retry code to dongle |
# 14 Nov. 2007 Moved dongle spesific code to class Dongle from USPP |
# USPP is allmost standard now (standard USPP would work) |
# Artec USPP has serial open retry |
# 14 Nov. 2007 Improved help. |
# 10 Mar. 2008 Forced code to hw flow control settings made linux 1 byte read to 2 bytes |
# as dongle never reads 1 byte at the time |
# 18 Apr. 2008 Added file size boundary check on write to see if remaining size from |
# given offset fits the file size |
#------------------------------------------------------------------------- |
|
import os |
import sys |
import string |
import time |
import struct |
from sets import * |
from struct import * |
|
#### inline of artec FTDI spesific Uspp code ################################################### |
|
########################################################################## |
# USPP Library (Universal Serial Port Python Library) |
# |
# Copyright (C) 2006 Isaac Barona <ibarona@gmail.com> |
# |
# This library is free software; you can redistribute it and/or |
# modify it under the terms of the GNU Lesser General Public |
# License as published by the Free Software Foundation; either |
# version 2.1 of the License, or (at your option) any later version. |
# |
# This library is distributed in the hope that it will be useful, |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
# Lesser General Public License for more details. |
|
# You should have received a copy of the GNU Lesser General Public |
# License along with this library; if not, write to the Free Software |
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
########################################################################## |
|
#------------------------------------------------------------------------- |
# Project: USPP Library (Universal Serial Port Python Library) |
# Name: uspp.py |
# Purpose: Main module. Imports the correct module for the platform |
# in which it is running. |
# |
# Author: Isaac Barona Martinez <ibarona@gmail.com> |
# Contributors: |
|
# Douglas Jones <dfj23@drexel.edu> |
# J.Grauheding <juergen.grauheding@a-city.de> |
# J.Toomessoo jyrit@artecdesign.ee |
# |
# Copyright: (c) 2006 by Isaac Barona Martinez |
# Licence: LGPL |
# |
# Created: 26 June 2001 |
# History: |
# 05/08/2001: Release version 0.1. |
# 24/02/2006: Final version 1.0. |
# 10/11/2007: Added open retry code to dongle |
# by Jyri Toomessoo jyrit@artecdesign.ee |
# 14/11/2007: Moved dongle spesific code to class Dongle from USPP |
# USPP is allmost standard now (standard USPP would work) |
# Artec USPP has serial open retry |
# by Jyri Toomessoo jyrit@artecdesign.ee |
# 10/03/2008: Forced code to hw flow control settings made linux 1 byte read to 2 bytes |
# as dongle never reads 1 byte at the time |
# by Jyri Toomessoo jyrit@artecdesign.ee |
# 10/03/2008: Copose single infile bundle for FTDI USB serial 1.2 |
# this is nonuniversal modification of the code to suite the need of Artec Design Dongle |
# by Jyri Toomessoo jyrit@artecdesign.ee |
#------------------------------------------------------------------------- |
|
|
drv_ok = 0 |
if sys.platform=='win32': |
print "Windows platform detected:" |
if drv_ok == 0: |
try: |
from win32file import * |
from win32event import * |
import win32con |
import exceptions |
|
print "Using VCP FTDI driver" |
except ImportError,SerialPortException: |
print "Python for winiows extensions for COM not found" |
print "(see https://sourceforge.net/projects/pywin32/)" |
print "Could not find any usable support for FTDI chip in python" |
print "Try installing python support from one of the links." |
sys.exit() |
elif sys.platform=='linux2': |
from termios import * |
import fcntl |
import exceptions |
import array |
print "Linux platform detected:" |
else: |
sys.exit('Sorry, no implementation for this platform yet') |
|
|
|
class SerialPortException(exceptions.Exception): |
"""Exception raise in the SerialPort methods""" |
def __init__(self, args=None): |
self.args=args |
def __str__(self): |
return repr(self.args) |
|
|
if sys.platform=='win32': |
class SerialPortWin: |
BaudRatesDic={110: CBR_110, |
300: CBR_300, |
600: CBR_600, |
1200: CBR_1200, |
2400: CBR_2400, |
4800: CBR_4800, |
9600: CBR_9600, |
19200: CBR_19200, |
38400: CBR_38400, |
57600: CBR_57600, |
115200: CBR_115200, |
128000: CBR_128000, |
256000: CBR_256000 |
} |
|
def __init__(self, dev, timeout=None, speed=115200, mode='232', params=None): |
self.__devName, self.__timeout, self.__speed=dev, timeout, speed |
self.__mode=mode |
self.__params=params |
self.__speed = 0 |
self.__reopen = 0 |
while 1: |
try: |
self.__handle=CreateFile (dev, |
win32con.GENERIC_READ|win32con.GENERIC_WRITE, |
0, # exclusive access |
None, # no security |
win32con.OPEN_EXISTING, |
win32con.FILE_ATTRIBUTE_NORMAL, |
None) |
break |
|
except: |
n=0 |
while (n < 2000000): |
n += 1; |
self.__reopen = self.__reopen + 1 |
if self.__reopen > 32: |
print "Port does not exist..." |
raise SerialPortException('Port does not exist...') |
break |
#sys.exit() |
self.__configure() |
|
def __del__(self): |
if self.__speed: |
try: |
CloseHandle(self.__handle) |
except: |
raise SerialPortException('Unable to close port') |
|
|
|
|
def __configure(self): |
if not self.__speed: |
self.__speed=115200 |
# Tell the port we want a notification on each char |
SetCommMask(self.__handle, EV_RXCHAR) |
# Setup a 4k buffer |
SetupComm(self.__handle, 4096, 4096) |
# Remove anything that was there |
PurgeComm(self.__handle, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR| |
PURGE_RXCLEAR) |
if self.__timeout==None: |
timeouts= 0, 0, 0, 0, 0 |
elif self.__timeout==0: |
timeouts = win32con.MAXDWORD, 0, 0, 0, 1000 |
else: |
timeouts= self.__timeout, 0, self.__timeout, 0 , 1000 |
SetCommTimeouts(self.__handle, timeouts) |
|
# Setup the connection info |
dcb=GetCommState(self.__handle) |
dcb.BaudRate=SerialPortWin.BaudRatesDic[self.__speed] |
if not self.__params: |
dcb.ByteSize=8 |
dcb.Parity=NOPARITY |
dcb.StopBits=ONESTOPBIT |
dcb.fRtsControl=RTS_CONTROL_ENABLE |
dcb.fOutxCtsFlow=1 |
else: |
dcb.ByteSize, dcb.Parity, dcb.StopBits=self.__params |
SetCommState(self.__handle, dcb) |
|
|
def fileno(self): |
return self.__handle |
|
|
def read(self, num=1): |
(Br, buff) = ReadFile(self.__handle, num) |
if len(buff)<>num and self.__timeout!=0: # Time-out |
print 'Expected %i bytes but got %i before timeout'%(num,len(buff)) |
raise SerialPortException('Timeout') |
else: |
return buff |
|
|
def readline(self): |
s = '' |
while not '\n' in s: |
s = s+SerialPortWin.read(self,1) |
|
return s |
|
|
def write(self, s): |
"""Write the string s to the serial port""" |
errCode = 0 |
overlapped=OVERLAPPED() |
overlapped.hEvent=CreateEvent(None, 0,0, None) |
(errCode, bytesWritten) = WriteFile(self.__handle, s,overlapped) |
# Wait for the write to complete |
WaitForSingleObject(overlapped.hEvent, INFINITE) |
return bytesWritten |
|
def inWaiting(self): |
"""Returns the number of bytes waiting to be read""" |
flags, comstat = ClearCommError(self.__handle) |
return comstat.cbInQue |
|
def flush(self): |
"""Discards all bytes from the output or input buffer""" |
PurgeComm(self.__handle, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR| |
PURGE_RXCLEAR) |
|
|
|
if sys.platform=='linux2': |
class SerialPortLin: |
"""Encapsulate methods for accesing to a serial port.""" |
|
BaudRatesDic={ |
110: B110, |
300: B300, |
600: B600, |
1200: B1200, |
2400: B2400, |
4800: B4800, |
9600: B9600, |
19200: B19200, |
38400: B38400, |
57600: B57600, |
115200: B115200, |
230400: B230400 |
} |
buf = array.array('h', '\000'*4) |
|
def __init__(self, dev, timeout=None, speed=115200, mode='232', params=None): |
self.__devName, self.__timeout, self.__speed=dev, timeout, speed |
self.__mode=mode |
self.__params=params |
self.__speed = 0 |
self.__reopen = 0 |
while 1: |
try: |
self.__handle=os.open(dev, os.O_RDWR) |
break |
|
except: |
n=0 |
while (n < 2000000): |
n += 1; |
self.__reopen = self.__reopen + 1 |
if self.__reopen > 32: |
print "Port does not exist..." |
raise SerialPortException('Port does not exist...') |
break |
|
self.__configure() |
|
def __del__(self): |
if self.__speed: |
#tcsetattr(self.__handle, TCSANOW, self.__oldmode) |
pass |
try: |
pass |
os.close(self.__handle) |
except IOError: |
raise SerialPortException('Unable to close port') |
|
|
def __configure(self): |
if not self.__speed: |
self.__speed=115200 |
|
# Save the initial port configuration |
self.__oldmode=tcgetattr(self.__handle) |
if not self.__params: |
# print "Create linux params for serialport..." |
# self.__params is a list of attributes of the file descriptor |
# self.__handle as follows: |
# [c_iflag, c_oflag, c_cflag, c_lflag, c_ispeed, c_ospeed, cc] |
# where cc is a list of the tty special characters. |
self.__params=[] |
# c_iflag |
self.__params.append(IGNPAR) |
# c_oflag |
self.__params.append(0) |
# c_cflag |
self.__params.append(CS8|CREAD|CRTSCTS) |
# c_lflag |
self.__params.append(0) |
# c_ispeed |
self.__params.append(SerialPortLin.BaudRatesDic[self.__speed]) |
# c_ospeed |
self.__params.append(SerialPortLin.BaudRatesDic[self.__speed]) |
cc=[0]*NCCS |
if self.__timeout==None: |
# A reading is only complete when VMIN characters have |
# been received (blocking reading) |
cc[VMIN]=1 |
cc[VTIME]=0 |
elif self.__timeout==0: |
cc[VMIN]=0 |
cc[VTIME]=0 |
else: |
cc[VMIN]=0 |
cc[VTIME]=self.__timeout #/100 |
self.__params.append(cc) # c_cc |
|
tcsetattr(self.__handle, TCSANOW, self.__params) |
|
|
def fileno(self): |
return self.__handle |
|
|
def __read1(self): |
tryCnt = 0 |
byte = "" |
while(len(byte)==0 and tryCnt<10): |
tryCnt+=1 |
byte = os.read(self.__handle, 2) |
if len(byte)==0 and self.__timeout!=0: # Time-out |
print 'Time out cnt was %i'%(tryCnt) |
print 'Expected 1 byte but got %i before timeout'%(len(byte)) |
sys.stdout.flush() |
raise SerialPortException('Timeout') |
else: |
return byte |
|
|
def read(self, num=1): |
s='' |
for i in range(num/2): |
s=s+SerialPortLin.__read1(self) |
return s |
|
|
def readline(self): |
|
s = '' |
while not '\n' in s: |
s = s+SerialPortLin.__read1(self) |
|
return s |
|
|
def write(self, s): |
"""Write the string s to the serial port""" |
return os.write(self.__handle, s) |
|
def inWaiting(self): |
"""Returns the number of bytes waiting to be read""" |
data = struct.pack("L", 0) |
data=fcntl.ioctl(self.__handle, TIOCINQ, data) |
return struct.unpack("L", data)[0] |
|
def outWaiting(self): |
"""Returns the number of bytes waiting to be write |
mod. by J.Grauheding |
result needs some finetunning |
""" |
rbuf=fcntl.ioctl(self.__handle, TIOCOUTQ, self.buf) |
return rbuf |
|
|
def flush(self): |
"""Discards all bytes from the output or input buffer""" |
tcflush(self.__handle, TCIOFLUSH) |
|
|
|
#### end inline of artec FTDI spesific Uspp code ############################################### |
|
|
#### Dongle code starts here ################################################################## |
|
|
#### global funcs #### |
def usage(s): |
print "Artec USB Dongle programming utility ver. 2.52" |
print "Usage:" |
print "Write file : ",s," [-vq] -c <name> <file> <offset>" |
print "Readback file : ",s," [-vq] -c <name> [-vq] -r <offset> <length> <file>" |
print "Options:" |
print " <file> <offset> When file and offset are given file will be written to dongle" |
print " file: File name to be written to dongle" |
print " offset: Specifies data writing starting point in bytes to 4M window" |
print " For ThinCan boot code the offset = 4M - filesize. To write" |
print " 256K file the offset must be 3840K" |
print " " |
print " -c <name> Indicate port name where the USB Serial Device is" |
print " name: COM port name in Windows or Linux Examples: COM3,/dev/ttyS3" |
print " See Device Manager in windows for USB Serial Port number" |
print " " |
print " -v Enable verbose mode. Displays more progress information" |
print " " |
print " -q Perform flash query to see if dongle flash is responding" |
print " " |
print " -r <offset> <length> <file> Readback data. Available window size is 4MB" |
print " offset: Offset byte addres inside 4MB window. Example: 1M" |
print " use M for MegaBytes, K for KiloBytes, none for bytes" |
print " use 0x prefix to indicate hexademical number format" |
print " length: Amount in bytes to read starting from offset. Example: 1M" |
print " use M for MegaBytes, K for KiloBytes, none for bytes" |
print " file: Filename where data will be written" |
print " " |
print " -e Erase device. Erases Full 4 MegaBytes" |
print "Board test options: " |
print " -t Marching one and zero test. Device must be empty" |
print " To test dongle erase the flash with command -e" |
print " Enables dongle memory tests to be executed by user" |
print " " |
print " -b Leave flash blank after test. Used with option -t" |
print " -l Fast poll loop test. Does poll loop 1024 times" |
print " used to stress test connection" |
print "" |
print "Examples:" |
print "" |
print " ",s," -c COM3 loader.bin 0 " |
print " ",s," -c /dev/ttyS3 boot.bin 3840K" |
print " ",s," -c COM3 -r 0x3C0000 256K flashcontent.bin" |
###################### |
|
|
class DongleMode: |
def __init__(self): |
self.v = 0 |
self.f = 0 |
self.d = 0 |
self.q = 0 |
self.r = 0 |
self.t = 0 |
self.e = 0 |
self.b = 0 |
self.l = 0 |
self.filename="" |
self.portname="" |
self.address=-1 |
self.offset=-1 |
self.length=-1 |
self.version=4 |
|
def convParamStr(self,param): |
mult = 1 |
value = 0 |
str = param |
if str.find("K")>-1: |
mult = 1024 |
str=str.strip("K") |
if str.find("M")>-1: |
mult = 1024*1024 |
str=str.strip("M") |
try: |
if str.find("x")>-1: |
value = int(str,0)*mult #conver hex string to int |
else: |
value = int(str)*mult #conver demical string to int |
except ValueError: |
print "Bad parameter format given for: ",param |
|
return value |
|
|
|
|
class Dongle: |
def __init__(self,name, baud, timeout): #time out in millis 1000 = 1s baud like 9600, 57600 |
self.mode = 0 |
try: |
if sys.platform=='win32': |
self.tty = SerialPortWin(name,timeout, baud) |
else: |
self.tty = SerialPortLin(name,timeout, baud) |
|
except SerialPortException , e: |
print "Unable to open port " + name |
sys.exit(); |
|
def testReturn(self,byteCount): |
i=0 |
while don.tty.inWaiting()<byteCount: |
i=i+1 |
if i==10000*byteCount: |
break |
if i==10000*byteCount: |
return 0 |
j=don.tty.inWaiting() |
#print "Tested in waiting %i needed %i"%(j,byteCount) |
return j ## ret two bytes |
|
def getReturn(self,byteCount): |
i=0 |
#while don.tty.inWaiting()<byteCount: |
# i=i+1 |
# time.sleep(0.1) |
# if i==100*byteCount: |
# print "Dongle not communicating" |
# #print "Read in waiting %i needed %i was %i"%(i,byteCount,don.tty.inWaiting()) |
# sys.exit() |
# break |
|
#i=don.tty.inWaiting() |
#print "Read in waiting %i needed %i was %i"%(i,byteCount,don.tty.inWaiting()) |
buf = don.tty.read(byteCount) |
#print "Got bytes =%i "%(len(buf)) |
return buf ## ret two bytes |
|
|
def write_command(self,command): |
lsb = command&0xff |
msb = (command>>8)&0xff |
self.write_2bytes(msb,lsb) |
|
def write_2bytes(self, msb,lsb): |
"""Write one word MSB,LSB to the serial port MSB first""" |
s = pack('BB', msb, lsb) |
ret = self.tty.write(s) |
if(ret<len(s)): |
print 'write_2byte: Wrote less then needed %i bytes from %i'%(ret,length(s)) |
# Wait for the write to complete |
#WaitForSingleObject(overlapped.hEvent, INFINITE) |
|
def get_address_buf(self,address): #set word address |
lsbyte = address&0xff |
byte = (address>>8)&0xff |
msbyte = (address>>16)&0xff |
buffer = "" |
buffer += chr(lsbyte) |
buffer += chr(0xA0) |
buffer += chr(byte) |
buffer += chr(0xA1) |
buffer += chr(msbyte) |
buffer += chr(0xA2) |
evaluate = (address>>24) |
if evaluate != 0: |
print "Addressign fault. Too large address passed" |
sys.exit() |
return buffer |
|
|
def set_address(self,address): #set word address |
lsbyte = address&0xff |
byte = (address>>8)&0xff |
msbyte = (address>>16)&0xff |
evaluate = (address>>24) |
if evaluate != 0: |
print "Addressign fault. Too large address passed" |
sys.exit() |
self.write_2bytes(lsbyte,0xA0) #set internal address to dongle |
self.write_2bytes(byte,0xA1) #set internal address to dongle |
self.write_2bytes(msbyte,0xA2) #send query command |
|
def read_data(self,wordCount,address): |
command = 0 |
byteCount = wordCount<<1 #calc byte count |
if wordCount>0 : |
command = (command|wordCount)<<8; |
command = command|0xCD |
self.set_address(address) # send read address |
self.write_command(command) # send get data command |
return self.getReturn(byteCount) |
else: |
print "Word count can't be under 1" |
sys.exit() |
|
|
def issue_blk_read(self): |
command = 0 |
wordCount = 0 |
byteCount = wordCount<<1 #calc byte count |
command = (command|wordCount)<<8; |
command = command|0xCD |
self.write_command(command) # send get data command |
|
|
|
|
def read_status(self): |
don.write_command(0x0070) # 0x0098 //clear status |
command = 0 |
wordCount= 1 #calc byte count |
byteCount = wordCount<<1 |
command = (command|wordCount)<<8; |
command = command|0xCD |
self.write_command(command) # send get data command |
return self.getReturn(byteCount) |
|
|
def get_block_no(self,address): |
return address >> 16 # 16 bit mode block is 64Kwords |
|
def wait_on_busy(self): |
exit=0 |
while exit==0: |
buf=self.read_status() |
statReg = ord(buf[0]) #8 bit reg |
if statReg>>7 == 1: |
exit=1 |
|
def parse_status(self): # use only after wait on busy commad to get result of the operation |
exit = 0 |
buf=self.read_status() |
statReg = ord(buf[0]) #8 bit reg |
if (statReg>>5)&1 == 1: |
print "Block erase suspended" |
exit = 1 |
if (statReg>>4)&3 == 3: |
print "Error in command order" #if bits 4 and 5 are set then |
exit = 1 |
if (statReg>>4)&3 == 1: |
print "Error in setting lock bit" |
exit = 1 |
if (statReg>>3)&1 == 1: |
print "Low Programming Voltage Detected, Operation Aborted" |
exit = 1 |
if (statReg>>2)&1 == 1: |
print "Programming suspended" |
exit = 1 |
if (statReg>>1)&1 == 1: |
print "Block lock bit detected" |
exit = 1 |
if exit == 1: |
sys.exit() |
|
def erase_block(self,blockNo): |
blockAddress = blockNo << 16 |
command = 0x0020 |
self.set_address(blockAddress) |
self.write_command(command) #issue block erase |
command = 0x00D0 |
self.write_command(command) #issue block erase confirm |
#self.wait_on_busy() |
#self.parse_status() |
|
def buffer_write(self,wordCount,startAddress,buffer): |
# to speed up buffer writing compose all commands into one buffer |
# instead of multiple single writes this is needed as the FTDI chip |
# round lag is amazingly large with VCOM drivers |
#u = len(buffer) |
if len(buffer)<32: #don't ever make unaligned writes |
i=len(buffer) |
while len(buffer)<32: |
buffer += "\xff" |
adrBuf = self.get_address_buf(startAddress) #6 bytes total |
cmd_e8="" #8 bytes total |
cmd_e8+= chr(16) #make it always 16 wordCount |
cmd_e8+= chr(0xE8) |
cmd_wcnt="" #10 bytes total |
cmd_wcnt+= chr(0x00) |
cmd_wcnt+= chr(16-1) |
cmd_buf="" #12 bytes total |
cmd_buf+= chr(0x00) |
cmd_buf+= chr(0xD0) |
wr_buffer_cmd = adrBuf + cmd_e8 + cmd_wcnt + buffer + cmd_buf #44 bytes total |
self.write_buf_cmd(wr_buffer_cmd) |
|
if self.mode.version <5: |
n = 0 |
if sys.platform=='win32': |
while (n < 1024): |
n += 1; |
elif sys.platform=='linux2': |
#Linux FTDI VCP driver is way faster and needs longer grace time than windows driver |
while (n < 1024*8): |
n += 1; |
|
def write_buf_cmd(self, buffer): |
"""Write one word MSB,LSB to the serial port MSB first""" |
a=0 |
s="" |
if (len(buffer) < 44): # if buffer is shorter than expected then pad with read array mode commands |
i=0 |
while i<len(buffer): |
print '0x%02x'%(ord(buffer[i])) |
i+=1 |
while(a < len(buffer)): |
if a < 10: |
s= pack('2c', buffer[a], buffer[a+1]) |
self.tty.write(s) |
elif a < len(buffer)-2: |
s= pack('2c', buffer[a+1], buffer[a]) |
self.tty.write(s) |
elif len(buffer)==2: |
s=pack('2c', buffer[a], buffer[a+1]) |
self.tty.write(s) |
else: |
s=pack('2c', buffer[a], chr(0xFF)) |
self.tty.write(s) |
a+=2 |
else: |
#first 10 bytes are in correct order + 32 data bytes are in wrong order and + 2 confirm bytes are in correct order |
s=pack('44c', |
buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5], buffer[6], buffer[7], |
buffer[8], buffer[9], buffer[11], buffer[10], buffer[13], buffer[12], buffer[15], buffer[14], |
buffer[17], buffer[16], buffer[19], buffer[18], buffer[21], buffer[20], buffer[23], buffer[22], |
buffer[25], buffer[24], buffer[27], buffer[26], buffer[29], buffer[28], buffer[31], buffer[30], |
buffer[33], buffer[32], buffer[35], buffer[34], buffer[37], buffer[36], buffer[39], buffer[38], |
buffer[41], buffer[40], buffer[42], buffer[43] |
) |
|
ret = self.tty.write(s) |
|
|
|
################## Main program ######################### |
|
|
last_ops = 0 |
mode = DongleMode() |
# PARSE ARGUMENTS |
for arg in sys.argv: |
if len(sys.argv) == 1: # if no arguments display help |
#usage(sys.argv[0]) |
usage("dongle.py") |
sys.exit() |
if arg in ("-h","--help","/help","/h"): |
#usage(sys.argv[0]) |
usage("dongle.py") |
sys.exit() |
if arg in ("-c"): |
last_ops = sys.argv.index(arg) + 1 #if remains last set of options from here start ordered strings |
i = sys.argv.index(arg) |
print "Opening port: "+sys.argv[i+1] |
mode.portname = sys.argv[i+1] # next element after -c open port for usage |
if arg[0]=="-" and arg[1]!="c": # if other opptions |
# parse all options in this |
last_ops = sys.argv.index(arg) #if remains last set of options from here start ordered strings |
ops = arg[1:]# get all besides the - sign |
for op in ops: |
if op=="q": |
mode.q = 1 |
if op=="v": |
mode.v = 1 |
if op=="f": |
mode.f = 1 |
if op=="d": |
mode.d = 1 |
if op=="r": |
mode.r = 1 |
if op=="t": |
mode.t = 1 |
if op=="e": |
mode.e = 1 |
if op=="b": |
mode.b = 1 |
if op=="l": |
mode.l = 1 |
else: |
i = sys.argv.index(arg) |
if i == last_ops + 1: |
if mode.r==1: |
mode.offset=mode.convParamStr(arg) |
else: |
mode.filename=arg |
if i == last_ops + 2: |
if mode.r==1: |
mode.length=mode.convParamStr(arg) |
else: |
mode.address=mode.convParamStr(arg) |
|
if i == last_ops + 3: |
if mode.r==1: |
mode.filename=arg |
else: |
print "Too many parameters provided" |
sys.exit() |
if i > last_ops + 3: |
print "Too many parameters provided" |
sys.exit() |
|
# END PARSE ARGUMENTS |
|
if mode.portname=="": |
print "No port name given see -h for help" |
sys.exit() |
else: |
# test PC speed to find sutable delay for linux driver |
# to get 250 us |
mytime = time.clock() |
n = 0 |
while (n < 100000): |
n += 1; |
k10Time = time.clock() - mytime # time per 10000 while cycles |
wait = k10Time/100000.0 # time per while cycle |
wait = (0.00025/wait) * 1.20 # count for 250us + safe margin |
# ok done |
reopened = 0 |
|
|
if sys.platform=='win32': |
don = Dongle(mode.portname,256000,6000) |
elif sys.platform=='linux2': |
don = Dongle(mode.portname,230400,6000) |
#don.tty.cts() |
else: |
sys.exit('Sorry, no implementation for this platform yet') |
|
|
don.tty.wait = wait |
while 1: |
don.write_command(0x0050) # 0x0098 |
don.write_command(0x00C5) #send dongle check internal command |
don_ret=don.testReturn(2) |
if don_ret==2: |
break |
if reopened == 3: |
print 'Dongle connected, but does not communicate' |
sys.exit() |
reopened = reopened + 1 |
# reopen and do new cycle |
if sys.platform=='win32': |
don = Dongle(mode.portname,256000,6000) |
elif sys.platform=='linux2': |
don = Dongle(mode.portname,230400,6000) |
#self.tty.cts() |
else: |
sys.exit('Sorry, no implementation for this platform yet') |
don.tty.wait = wait |
|
buf=don.getReturn(2) # two bytes expected to this command |
if ord(buf[1])==0x32 and ord(buf[0])==0x10: |
print "Dongle OK" |
else: |
print 'Dongle returned on open: %02x %02x '%(ord(buf[1]), ord(buf[0])) |
don.write_command(0x01C5) #try getting dongle HW ver (works since 05 before that returns 0x3210) |
buf=don.getReturn(2) # two bytes expected to this command |
if ord(buf[1])==0x86 and ord(buf[0])>0x04: |
mode.version = ord(buf[0]) |
don.mode = mode |
print 'Dongle HW version code is %02x %02x'%(ord(buf[1]), ord(buf[0])) |
else: |
don.mode = mode |
print 'Dongle HW version code is smaller than 05 some features have been improved on' |
print 'HW code and Quartus FPGA binary file are available at:' |
print 'http://www.opencores.org/projects.cgi/web/usb_dongle_fpga/overview' |
print 'Programming is possible with Altera Quartus WE and BYTEBLASTER II cable or' |
print 'compatible clone like X-Blaster http://www.customcircuitsolutions.com/cable.html' |
|
if mode.q == 1: # perform a query from dongle |
|
buf=don.read_data(4,0x0) # word count and word address |
don.write_command(0x0050) # 0x0098 |
don.write_command(0x0098) # 0x0098 |
buf=don.read_data(3,0x000010) # word count and word address |
if ord(buf[0])==0x51 and ord(buf[2])==0x52 and ord(buf[4])==0x59: |
buf=don.read_data(2,0x000000) # word count and word address |
print 'Query OK, Flash Factory Code is: 0x%02x device: 0x%02x '%(ord(buf[0]),ord(buf[2])) |
buf=don.read_data(2,0x000002) |
print 'lock bit is 0x%02x 0x%02x'%(ord(buf[0]),ord(buf[1])) |
else: |
print "Got bad Flash query data:" |
print 'Query address 0x10 = 0x%02x%02x '%(ord(buf[1]),ord(buf[0])) |
print 'Query address 0x12 = 0x%02x%02x '%(ord(buf[3]),ord(buf[2])) |
print 'Query address 0x14 = 0x%02x%02x '%(ord(buf[5]),ord(buf[4])) |
print "Read byte count:",len(buf) |
|
don.write_command(0x00FF) # 0x0098 |
buf=don.read_data(4,0xff57c0>>1) # word count and word address |
|
print 'Data: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x '%(ord(buf[1]),ord(buf[0]),ord(buf[3]),ord(buf[2]),ord(buf[5]),ord(buf[4]),ord(buf[7]),ord(buf[6]) ) |
|
|
|
if mode.filename!="" and mode.address!=-1: |
#Calculate number of blocks and start of blocks |
size = 0 |
mode.address = mode.address>>1 #make word address |
try: |
f=open(mode.filename,"rb") |
f.seek(0,2) #seek to end |
size = f.tell() |
f.seek(0) #seek to start |
print 'File size %iK '%(size/1024) |
f.close() |
except IOError: |
print "IO Error on file open. File missing or no premission to open." |
sys.exit() |
#clear blockLock bits |
don.write_command(0x0060) # 0x0098 |
don.write_command(0x00D0) # 0x0098 |
if mode.version < 5: |
don.wait_on_busy() |
don.parse_status() |
wordSize = (size+ (size&1))>> 1 # round byte count up and make word address |
endBlock = don.get_block_no(mode.address+wordSize - 1) |
startBlock = don.get_block_no(mode.address) |
if endBlock >= 32: |
print "Given file does not fit into remaining space. File size is %i KB"%(size/1024) |
print "Space left from given offset is %i KB"%((4*1024*1024-mode.address*2)/1024) |
sys.exit() |
i=startBlock |
print 'Erasing from block %i to %i '%(i,endBlock) |
while i <= endBlock: |
if mode.v == 1: |
print 'Erasing block %i '%(i) |
else: |
sys.stdout.write(".") |
sys.stdout.flush() |
don.erase_block(i) |
if mode.version < 5: |
don.wait_on_busy() |
don.parse_status() #do this after programming all but uneaven ending |
i=i+1 |
if mode.v == 0: |
print " " |
#don.write_command(0x00FF) # 0x0098 |
#buf=don.read_data(4,0x000000) # word count and word address |
#print 'Data: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x '%(ord(buf[0]),ord(buf[1]),ord(buf[2]),ord(buf[3]),ord(buf[4]),ord(buf[5]),ord(buf[6]),ord(buf[7]) ) |
|
f=open(mode.filename,"rb") |
f.seek(0) #seek to start |
address= mode.address |
#don.set_address(address) |
print 'Writing %iK'%(size/1024) |
while 1: |
if (address/(1024*64) != (address-16)/(1024*64)) and address != mode.address: # get bytes from words if 512 |
if mode.v == 1: |
print 'Progress: %iK of %iK at 0x%06x'%((address-mode.address)/512,size/1024,address) |
else: |
sys.stdout.write(".") |
sys.stdout.flush() |
buf = f.read(32) #16 words is maximum write here bytes are read |
if len(buf)==32: |
don.buffer_write(16,address,buf) |
address = address + 16 |
elif len(buf)>0: |
don.parse_status() #do this after programming all but uneaven ending |
print "Doing an unaligned write..." |
length = len(buf) |
length = (length + (length&1))>> 1 #round up to get even word count |
buf = buf+"\xff" #pad just in case rounding took place |
don.buffer_write(len,address,buf) |
address = address + 16 #inc word address |
break |
else: |
break |
if mode.v == 0: |
print " " |
if mode.version >= 5: |
print "Waiting for buffers to empty" |
don.wait_on_busy() |
don.parse_status() #do this after programming all but uneaven ending |
print "Write DONE!" |
don.parse_status() #do this after programming all but uneaven ending |
f.close() |
|
if mode.r == 1: # perform a readback |
if mode.offset!=-1 and mode.length!=-1 and mode.filename!="": |
if mode.version >= 5: |
##################### from hw ver 5 readback code ################################################## |
blockCount = (mode.length>>17)+1 #read this many 64K word blocks |
mode.offset=mode.offset>>1 #make word offset |
lastLength = mode.length&0x0001FFFF |
mode.length= mode.length>>1 #make word length |
if mode.length < 512: |
print 'Reading %i bytes in single block '%(lastLength) |
else: |
print 'Reading %iK in %i blocks '%(mode.length/512,blockCount) |
don.write_command(0x00FF) # put flash to data read mode |
try: |
f=open(mode.filename,"wb") #if this fails no point in reading as there is nowhere to write |
address = mode.offset # set word address |
don.set_address(address) |
i=0 |
while (i<blockCount): |
don.issue_blk_read() # request 64K words from current address |
buf=don.getReturn(65536*2) #Read all words |
if (i==blockCount-1): #last block |
f.write(buf[:lastLength]) |
else: |
f.write(buf) ## must tuncate the buffer |
if mode.v == 1: |
print 'Got block %i'%(i+1) |
else: |
sys.stdout.write(".") |
sys.stdout.flush() |
i+=1 |
f.close() |
except IOError: |
print "IO Error on file open" |
sys.exit() |
##################### end from hw ver 5 readback code ############################################ |
else: |
##################### before hw ver 5 readback code ############################################### |
mode.offset=mode.offset>>1 #make word offset |
mode.length= mode.length>>1 #make word length |
print 'Reading %iK'%(mode.length/512) |
try: |
f=open(mode.filename,"wb") |
don.write_command(0x00FF) # put flash to data read mode |
address = mode.offset # set word address |
while 1: |
if address/(1024*32) != (address-128)/(1024*32): # get K bytes from words if 512 |
if mode.v == 1: |
print 'Progress: %iK of %iK'%((address-mode.offset)/512,mode.length/512) |
else: |
sys.stdout.write(".") |
sys.stdout.flush() |
buf=don.read_data(128,address) # word count and byte address read 64 words to speed up |
f.write(buf) |
#print "from address:",address<<1," ", len(buf) |
if address+128 >= (mode.offset + mode.length): # 2+64 estimates the end to end in right place |
break |
address = address + 128 #this is word address |
f.close() |
if mode.v == 0: |
print " " |
print "Readback done!" |
except IOError: |
print "IO Error on file open" |
sys.exit() |
##################### end before hw ver 5 readback code ################################################ |
else: |
print "Some of readback parameters missing..." |
print mode.offset,mode.length, mode.filename |
sys.exit() |
|
if mode.t == 1: # perform dongle test |
print "Dongle TEST" |
if mode.e == 1: |
#Erase Dongle |
print "Erasing" |
don.write_command(0x0060) # 0x0098 |
don.write_command(0x00D0) # 0x0098 |
don.wait_on_busy() |
don.parse_status() |
endBlock = 31 |
startBlock = 0 |
i=startBlock |
while i <= endBlock: |
if mode.v == 1: |
print 'Erasing block %i '%(i) |
else: |
sys.stdout.write(".") |
sys.stdout.flush() |
don.erase_block(i) |
don.wait_on_busy() |
don.parse_status() #do this after programming all but uneaven ending |
i=i+1 |
if mode.v == 0: # add CRTL return to dots |
print "" |
#Do marching one test on data and address |
mode.length= 0 #make word length |
try: |
#Marching one test |
#--------------------------------------------------------------------------- |
address = 0x100000 # set word address |
data = 0x100000 |
while mode.length<20: # last address to test 0x20 0000 |
buf1=pack('BBBB', (0x000000FF&data),(0x0000FF00&data)>>8 ,(0x00FF0000&data)>>16 ,(0xFF0000&data)>>24 ) |
don.buffer_write(2,address,buf1) |
don.parse_status() #do this after programming all but uneaven ending |
don.write_command(0x00FF) # put flash to data read mode |
buf2=don.read_data(2,address) # word count and byte address read 64 words to speed up |
if buf1 != buf2: |
print 'IN %02x %02x %02x %02x '%(ord(buf1[3]), ord(buf1[2]),ord(buf1[1]), ord(buf1[0])) |
print 'OUT %02x %02x %02x %02x '%(ord(buf2[3]), ord(buf2[2]),ord(buf2[1]), ord(buf2[0])) |
print "Test FAIL!!!!!" |
sys.exit() |
address = address >> 1 |
if address == 0x2: |
address = address >> 1 # 0x2 is written and will return zero on read as write new write will fail |
data = data >> 1 |
mode.length = mode.length + 1 |
buf2=don.read_data(1,0) #read first byte |
if ord(buf2[0]) != 0xFF: |
print "Test FAIL (At least one address line const. 0)!!!!!" |
sys.exit() |
#----------------------------------------------------------------------- |
#Marching zero test |
address = 0xFFEFFFFF # set word address |
data = 0x100000 |
while mode.length<18: # last address to test 0x20 0000 |
buf1=pack('BBBB', (0x000000FF&data),(0x0000FF00&data)>>8 ,(0x00FF0000&data)>>16 ,(0xFF0000&data)>>24 ) |
don.buffer_write(2,address,buf1) |
don.parse_status() #do this after programming all but uneaven ending |
don.write_command(0x00FF) # put flash to data read mode |
buf2=don.read_data(2,address&0x1FFFFF) # word count and byte address read 64 words to speed up |
if buf1 != buf2: |
print 'IN %02x %02x %02x %02x '%(ord(buf1[3]), ord(buf1[2]),ord(buf1[1]), ord(buf1[0])) |
print 'OUT %02x %02x %02x %02x '%(ord(buf2[3]), ord(buf2[2]),ord(buf2[1]), ord(buf2[0])) |
print "Test FAIL!!!!!" |
sys.exit() |
address = (address >> 1)|0xFF000000 |
data = data >> 1 |
mode.length = mode.length + 1 |
buf2=don.read_data(1,0x1FFFFF) #read first byte |
if ord(buf2[0]) != 0xFF: |
print "Test FAIL (At least two address lines bonded)!!!!!" |
sys.exit() |
if mode.b == 1: |
#Erase Dongle |
print "Erasing" |
don.write_command(0x0060) # 0x0098 |
don.write_command(0x00D0) # 0x0098 |
don.wait_on_busy() |
don.parse_status() |
endBlock = 31 |
startBlock = 0 |
i=startBlock |
while i <= endBlock: |
if mode.v == 1: |
print 'Blanking block %i '%(i) |
else: |
sys.stdout.write(".") |
sys.stdout.flush() |
don.erase_block(i) |
if mode.version < 5: |
don.wait_on_busy() |
don.parse_status() #do this after programming all but uneaven ending |
i=i+1 |
if mode.v == 0: |
print " " |
print "Test SUCCESSFUL!" |
sys.exit() |
except IOError: |
print "IO Error on file open" |
sys.exit() |
|
if mode.e == 1: # perform dongle test |
#Erase Dongle |
print "Erasing all" |
don.write_command(0x0060) # 0x0098 |
don.write_command(0x00D0) # 0x0098 |
if mode.version < 5: |
don.wait_on_busy() |
don.parse_status() |
endBlock = 31 |
startBlock = 0 |
i=startBlock |
while i <= endBlock: |
if mode.v == 1: |
print 'Erasing block %i '%(i) |
else: |
sys.stdout.write(".") |
sys.stdout.flush() |
don.erase_block(i) |
if mode.version < 5: |
don.wait_on_busy() |
don.parse_status() #do this after programming all but uneaven ending |
i=i+1 |
if mode.v == 0: # add CRTL return to dots |
print "" |
if mode.version >= 5: |
print "Waiting for buffers to empty" |
don.wait_on_busy() |
don.parse_status() #do this after programming all but uneaven ending |
print "Erase done." |
|
if mode.l == 1: # perform dongle test |
#Erase Dongle |
print "Status Loop test" |
i=1024 |
startTime = time.clock() |
while i > 0: |
sys.stdout.write(".") |
sys.stdout.flush() |
don.wait_on_busy() |
don.parse_status() #do this after programming all but uneaven ending |
i=i-1 |
if sys.platform=='win32': |
endTime = (time.clock()-startTime)/1024.0 |
print "\nSystem round delay is %4f ms"%(endTime*1000.0) |
sys.stdout.flush() |
########################################################## |
/AUTHORS
0,0 → 1,7
LPC dongle script |
|
Uspp inlined library |
|
|
Douglas Jones <dfj23@drexel.edu> |
J.Grauheding <juergen.grauheding@a-city.de> |
/Copyright
0,0 → 1,44
LPC Dongle script dongle.py |
|
Copyright (C) 2008 Artec Design <jyrit@artecdesign.ee> |
|
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Lesser General Public |
License as published by the Free Software Foundation; either |
version 2.1 of the License, or (at your option) any later version. |
|
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Lesser General Public License for more details. |
|
You should have received a copy of the GNU Lesser General Public |
License along with this library; if not, write to the Free Software |
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
|
|
The complete text of the GNU Lesser General Public License can be found in |
the file 'lesser.txt'. |
|
|
Inlined USPP Library (Universal Serial Port Python Library) |
|
|
|
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Lesser General Public |
License as published by the Free Software Foundation; either |
version 2.1 of the License, or (at your option) any later version. |
|
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Lesser General Public License for more details. |
|
You should have received a copy of the GNU Lesser General Public |
License along with this library; if not, write to the Free Software |
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
|
|
The complete text of the GNU Lesser General Public License can be found in |
the file 'lesser.txt'. |
/readme.txt
0,0 → 1,11
Linux: |
On linux only python installation is needed |
and usually python is included. |
|
|
Windows: |
To use the python script on windows |
Python for Windows extensions have to be installed |
|
http://sourceforge.net/projects/pywin32 |
|
/lesser.txt
0,0 → 1,504
GNU LESSER GENERAL PUBLIC LICENSE |
Version 2.1, February 1999 |
|
Copyright (C) 1991, 1999 Free Software Foundation, Inc. |
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
Everyone is permitted to copy and distribute verbatim copies |
of this license document, but changing it is not allowed. |
|
[This is the first released version of the Lesser GPL. It also counts |
as the successor of the GNU Library Public License, version 2, hence |
the version number 2.1.] |
|
Preamble |
|
The licenses for most software are designed to take away your |
freedom to share and change it. By contrast, the GNU General Public |
Licenses are intended to guarantee your freedom to share and change |
free software--to make sure the software is free for all its users. |
|
This license, the Lesser General Public License, applies to some |
specially designated software packages--typically libraries--of the |
Free Software Foundation and other authors who decide to use it. You |
can use it too, but we suggest you first think carefully about whether |
this license or the ordinary General Public License is the better |
strategy to use in any particular case, based on the explanations below. |
|
When we speak of free software, we are referring to freedom of use, |
not price. Our General Public Licenses are designed to make sure that |
you have the freedom to distribute copies of free software (and charge |
for this service if you wish); that you receive source code or can get |
it if you want it; that you can change the software and use pieces of |
it in new free programs; and that you are informed that you can do |
these things. |
|
To protect your rights, we need to make restrictions that forbid |
distributors to deny you these rights or to ask you to surrender these |
rights. These restrictions translate to certain responsibilities for |
you if you distribute copies of the library or if you modify it. |
|
For example, if you distribute copies of the library, whether gratis |
or for a fee, you must give the recipients all the rights that we gave |
you. You must make sure that they, too, receive or can get the source |
code. If you link other code with the library, you must provide |
complete object files to the recipients, so that they can relink them |
with the library after making changes to the library and recompiling |
it. And you must show them these terms so they know their rights. |
|
We protect your rights with a two-step method: (1) we copyright the |
library, and (2) we offer you this license, which gives you legal |
permission to copy, distribute and/or modify the library. |
|
To protect each distributor, we want to make it very clear that |
there is no warranty for the free library. Also, if the library is |
modified by someone else and passed on, the recipients should know |
that what they have is not the original version, so that the original |
author's reputation will not be affected by problems that might be |
introduced by others. |
|
Finally, software patents pose a constant threat to the existence of |
any free program. We wish to make sure that a company cannot |
effectively restrict the users of a free program by obtaining a |
restrictive license from a patent holder. Therefore, we insist that |
any patent license obtained for a version of the library must be |
consistent with the full freedom of use specified in this license. |
|
Most GNU software, including some libraries, is covered by the |
ordinary GNU General Public License. This license, the GNU Lesser |
General Public License, applies to certain designated libraries, and |
is quite different from the ordinary General Public License. We use |
this license for certain libraries in order to permit linking those |
libraries into non-free programs. |
|
When a program is linked with a library, whether statically or using |
a shared library, the combination of the two is legally speaking a |
combined work, a derivative of the original library. The ordinary |
General Public License therefore permits such linking only if the |
entire combination fits its criteria of freedom. The Lesser General |
Public License permits more lax criteria for linking other code with |
the library. |
|
We call this license the "Lesser" General Public License because it |
does Less to protect the user's freedom than the ordinary General |
Public License. It also provides other free software developers Less |
of an advantage over competing non-free programs. These disadvantages |
are the reason we use the ordinary General Public License for many |
libraries. However, the Lesser license provides advantages in certain |
special circumstances. |
|
For example, on rare occasions, there may be a special need to |
encourage the widest possible use of a certain library, so that it becomes |
a de-facto standard. To achieve this, non-free programs must be |
allowed to use the library. A more frequent case is that a free |
library does the same job as widely used non-free libraries. In this |
case, there is little to gain by limiting the free library to free |
software only, so we use the Lesser General Public License. |
|
In other cases, permission to use a particular library in non-free |
programs enables a greater number of people to use a large body of |
free software. For example, permission to use the GNU C Library in |
non-free programs enables many more people to use the whole GNU |
operating system, as well as its variant, the GNU/Linux operating |
system. |
|
Although the Lesser General Public License is Less protective of the |
users' freedom, it does ensure that the user of a program that is |
linked with the Library has the freedom and the wherewithal to run |
that program using a modified version of the Library. |
|
The precise terms and conditions for copying, distribution and |
modification follow. Pay close attention to the difference between a |
"work based on the library" and a "work that uses the library". The |
former contains code derived from the library, whereas the latter must |
be combined with the library in order to run. |
|
GNU LESSER GENERAL PUBLIC LICENSE |
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION |
|
0. This License Agreement applies to any software library or other |
program which contains a notice placed by the copyright holder or |
other authorized party saying it may be distributed under the terms of |
this Lesser General Public License (also called "this License"). |
Each licensee is addressed as "you". |
|
A "library" means a collection of software functions and/or data |
prepared so as to be conveniently linked with application programs |
(which use some of those functions and data) to form executables. |
|
The "Library", below, refers to any such software library or work |
which has been distributed under these terms. A "work based on the |
Library" means either the Library or any derivative work under |
copyright law: that is to say, a work containing the Library or a |
portion of it, either verbatim or with modifications and/or translated |
straightforwardly into another language. (Hereinafter, translation is |
included without limitation in the term "modification".) |
|
"Source code" for a work means the preferred form of the work for |
making modifications to it. For a library, complete source code means |
all the source code for all modules it contains, plus any associated |
interface definition files, plus the scripts used to control compilation |
and installation of the library. |
|
Activities other than copying, distribution and modification are not |
covered by this License; they are outside its scope. The act of |
running a program using the Library is not restricted, and output from |
such a program is covered only if its contents constitute a work based |
on the Library (independent of the use of the Library in a tool for |
writing it). Whether that is true depends on what the Library does |
and what the program that uses the Library does. |
|
1. You may copy and distribute verbatim copies of the Library's |
complete source code as you receive it, in any medium, provided that |
you conspicuously and appropriately publish on each copy an |
appropriate copyright notice and disclaimer of warranty; keep intact |
all the notices that refer to this License and to the absence of any |
warranty; and distribute a copy of this License along with the |
Library. |
|
You may charge a fee for the physical act of transferring a copy, |
and you may at your option offer warranty protection in exchange for a |
fee. |
|
2. You may modify your copy or copies of the Library or any portion |
of it, thus forming a work based on the Library, and copy and |
distribute such modifications or work under the terms of Section 1 |
above, provided that you also meet all of these conditions: |
|
a) The modified work must itself be a software library. |
|
b) You must cause the files modified to carry prominent notices |
stating that you changed the files and the date of any change. |
|
c) You must cause the whole of the work to be licensed at no |
charge to all third parties under the terms of this License. |
|
d) If a facility in the modified Library refers to a function or a |
table of data to be supplied by an application program that uses |
the facility, other than as an argument passed when the facility |
is invoked, then you must make a good faith effort to ensure that, |
in the event an application does not supply such function or |
table, the facility still operates, and performs whatever part of |
its purpose remains meaningful. |
|
(For example, a function in a library to compute square roots has |
a purpose that is entirely well-defined independent of the |
application. Therefore, Subsection 2d requires that any |
application-supplied function or table used by this function must |
be optional: if the application does not supply it, the square |
root function must still compute square roots.) |
|
These requirements apply to the modified work as a whole. If |
identifiable sections of that work are not derived from the Library, |
and can be reasonably considered independent and separate works in |
themselves, then this License, and its terms, do not apply to those |
sections when you distribute them as separate works. But when you |
distribute the same sections as part of a whole which is a work based |
on the Library, the distribution of the whole must be on the terms of |
this License, whose permissions for other licensees extend to the |
entire whole, and thus to each and every part regardless of who wrote |
it. |
|
Thus, it is not the intent of this section to claim rights or contest |
your rights to work written entirely by you; rather, the intent is to |
exercise the right to control the distribution of derivative or |
collective works based on the Library. |
|
In addition, mere aggregation of another work not based on the Library |
with the Library (or with a work based on the Library) on a volume of |
a storage or distribution medium does not bring the other work under |
the scope of this License. |
|
3. You may opt to apply the terms of the ordinary GNU General Public |
License instead of this License to a given copy of the Library. To do |
this, you must alter all the notices that refer to this License, so |
that they refer to the ordinary GNU General Public License, version 2, |
instead of to this License. (If a newer version than version 2 of the |
ordinary GNU General Public License has appeared, then you can specify |
that version instead if you wish.) Do not make any other change in |
these notices. |
|
Once this change is made in a given copy, it is irreversible for |
that copy, so the ordinary GNU General Public License applies to all |
subsequent copies and derivative works made from that copy. |
|
This option is useful when you wish to copy part of the code of |
the Library into a program that is not a library. |
|
4. You may copy and distribute the Library (or a portion or |
derivative of it, under Section 2) in object code or executable form |
under the terms of Sections 1 and 2 above provided that you accompany |
it with the complete corresponding machine-readable source code, which |
must be distributed under the terms of Sections 1 and 2 above on a |
medium customarily used for software interchange. |
|
If distribution of object code is made by offering access to copy |
from a designated place, then offering equivalent access to copy the |
source code from the same place satisfies the requirement to |
distribute the source code, even though third parties are not |
compelled to copy the source along with the object code. |
|
5. A program that contains no derivative of any portion of the |
Library, but is designed to work with the Library by being compiled or |
linked with it, is called a "work that uses the Library". Such a |
work, in isolation, is not a derivative work of the Library, and |
therefore falls outside the scope of this License. |
|
However, linking a "work that uses the Library" with the Library |
creates an executable that is a derivative of the Library (because it |
contains portions of the Library), rather than a "work that uses the |
library". The executable is therefore covered by this License. |
Section 6 states terms for distribution of such executables. |
|
When a "work that uses the Library" uses material from a header file |
that is part of the Library, the object code for the work may be a |
derivative work of the Library even though the source code is not. |
Whether this is true is especially significant if the work can be |
linked without the Library, or if the work is itself a library. The |
threshold for this to be true is not precisely defined by law. |
|
If such an object file uses only numerical parameters, data |
structure layouts and accessors, and small macros and small inline |
functions (ten lines or less in length), then the use of the object |
file is unrestricted, regardless of whether it is legally a derivative |
work. (Executables containing this object code plus portions of the |
Library will still fall under Section 6.) |
|
Otherwise, if the work is a derivative of the Library, you may |
distribute the object code for the work under the terms of Section 6. |
Any executables containing that work also fall under Section 6, |
whether or not they are linked directly with the Library itself. |
|
6. As an exception to the Sections above, you may also combine or |
link a "work that uses the Library" with the Library to produce a |
work containing portions of the Library, and distribute that work |
under terms of your choice, provided that the terms permit |
modification of the work for the customer's own use and reverse |
engineering for debugging such modifications. |
|
You must give prominent notice with each copy of the work that the |
Library is used in it and that the Library and its use are covered by |
this License. You must supply a copy of this License. If the work |
during execution displays copyright notices, you must include the |
copyright notice for the Library among them, as well as a reference |
directing the user to the copy of this License. Also, you must do one |
of these things: |
|
a) Accompany the work with the complete corresponding |
machine-readable source code for the Library including whatever |
changes were used in the work (which must be distributed under |
Sections 1 and 2 above); and, if the work is an executable linked |
with the Library, with the complete machine-readable "work that |
uses the Library", as object code and/or source code, so that the |
user can modify the Library and then relink to produce a modified |
executable containing the modified Library. (It is understood |
that the user who changes the contents of definitions files in the |
Library will not necessarily be able to recompile the application |
to use the modified definitions.) |
|
b) Use a suitable shared library mechanism for linking with the |
Library. A suitable mechanism is one that (1) uses at run time a |
copy of the library already present on the user's computer system, |
rather than copying library functions into the executable, and (2) |
will operate properly with a modified version of the library, if |
the user installs one, as long as the modified version is |
interface-compatible with the version that the work was made with. |
|
c) Accompany the work with a written offer, valid for at |
least three years, to give the same user the materials |
specified in Subsection 6a, above, for a charge no more |
than the cost of performing this distribution. |
|
d) If distribution of the work is made by offering access to copy |
from a designated place, offer equivalent access to copy the above |
specified materials from the same place. |
|
e) Verify that the user has already received a copy of these |
materials or that you have already sent this user a copy. |
|
For an executable, the required form of the "work that uses the |
Library" must include any data and utility programs needed for |
reproducing the executable from it. However, as a special exception, |
the materials to be distributed need not include anything that is |
normally distributed (in either source or binary form) with the major |
components (compiler, kernel, and so on) of the operating system on |
which the executable runs, unless that component itself accompanies |
the executable. |
|
It may happen that this requirement contradicts the license |
restrictions of other proprietary libraries that do not normally |
accompany the operating system. Such a contradiction means you cannot |
use both them and the Library together in an executable that you |
distribute. |
|
7. You may place library facilities that are a work based on the |
Library side-by-side in a single library together with other library |
facilities not covered by this License, and distribute such a combined |
library, provided that the separate distribution of the work based on |
the Library and of the other library facilities is otherwise |
permitted, and provided that you do these two things: |
|
a) Accompany the combined library with a copy of the same work |
based on the Library, uncombined with any other library |
facilities. This must be distributed under the terms of the |
Sections above. |
|
b) Give prominent notice with the combined library of the fact |
that part of it is a work based on the Library, and explaining |
where to find the accompanying uncombined form of the same work. |
|
8. You may not copy, modify, sublicense, link with, or distribute |
the Library except as expressly provided under this License. Any |
attempt otherwise to copy, modify, sublicense, link with, or |
distribute the Library is void, and will automatically terminate your |
rights under this License. However, parties who have received copies, |
or rights, from you under this License will not have their licenses |
terminated so long as such parties remain in full compliance. |
|
9. You are not required to accept this License, since you have not |
signed it. However, nothing else grants you permission to modify or |
distribute the Library or its derivative works. These actions are |
prohibited by law if you do not accept this License. Therefore, by |
modifying or distributing the Library (or any work based on the |
Library), you indicate your acceptance of this License to do so, and |
all its terms and conditions for copying, distributing or modifying |
the Library or works based on it. |
|
10. Each time you redistribute the Library (or any work based on the |
Library), the recipient automatically receives a license from the |
original licensor to copy, distribute, link with or modify the Library |
subject to these terms and conditions. You may not impose any further |
restrictions on the recipients' exercise of the rights granted herein. |
You are not responsible for enforcing compliance by third parties with |
this License. |
|
11. If, as a consequence of a court judgment or allegation of patent |
infringement or for any other reason (not limited to patent issues), |
conditions are imposed on you (whether by court order, agreement or |
otherwise) that contradict the conditions of this License, they do not |
excuse you from the conditions of this License. If you cannot |
distribute so as to satisfy simultaneously your obligations under this |
License and any other pertinent obligations, then as a consequence you |
may not distribute the Library at all. For example, if a patent |
license would not permit royalty-free redistribution of the Library by |
all those who receive copies directly or indirectly through you, then |
the only way you could satisfy both it and this License would be to |
refrain entirely from distribution of the Library. |
|
If any portion of this section is held invalid or unenforceable under any |
particular circumstance, the balance of the section is intended to apply, |
and the section as a whole is intended to apply in other circumstances. |
|
It is not the purpose of this section to induce you to infringe any |
patents or other property right claims or to contest validity of any |
such claims; this section has the sole purpose of protecting the |
integrity of the free software distribution system which is |
implemented by public license practices. Many people have made |
generous contributions to the wide range of software distributed |
through that system in reliance on consistent application of that |
system; it is up to the author/donor to decide if he or she is willing |
to distribute software through any other system and a licensee cannot |
impose that choice. |
|
This section is intended to make thoroughly clear what is believed to |
be a consequence of the rest of this License. |
|
12. If the distribution and/or use of the Library is restricted in |
certain countries either by patents or by copyrighted interfaces, the |
original copyright holder who places the Library under this License may add |
an explicit geographical distribution limitation excluding those countries, |
so that distribution is permitted only in or among countries not thus |
excluded. In such case, this License incorporates the limitation as if |
written in the body of this License. |
|
13. The Free Software Foundation may publish revised and/or new |
versions of the Lesser General Public License from time to time. |
Such new versions will be similar in spirit to the present version, |
but may differ in detail to address new problems or concerns. |
|
Each version is given a distinguishing version number. If the Library |
specifies a version number of this License which applies to it and |
"any later version", you have the option of following the terms and |
conditions either of that version or of any later version published by |
the Free Software Foundation. If the Library does not specify a |
license version number, you may choose any version ever published by |
the Free Software Foundation. |
|
14. If you wish to incorporate parts of the Library into other free |
programs whose distribution conditions are incompatible with these, |
write to the author to ask for permission. For software which is |
copyrighted by the Free Software Foundation, write to the Free |
Software Foundation; we sometimes make exceptions for this. Our |
decision will be guided by the two goals of preserving the free status |
of all derivatives of our free software and of promoting the sharing |
and reuse of software generally. |
|
NO WARRANTY |
|
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO |
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. |
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR |
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY |
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE |
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE |
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME |
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. |
|
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN |
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY |
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU |
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR |
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE |
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING |
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A |
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF |
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH |
DAMAGES. |
|
END OF TERMS AND CONDITIONS |
|
How to Apply These Terms to Your New Libraries |
|
If you develop a new library, and you want it to be of the greatest |
possible use to the public, we recommend making it free software that |
everyone can redistribute and change. You can do so by permitting |
redistribution under these terms (or, alternatively, under the terms of the |
ordinary General Public License). |
|
To apply these terms, attach the following notices to the library. It is |
safest to attach them to the start of each source file to most effectively |
convey the exclusion of warranty; and each file should have at least the |
"copyright" line and a pointer to where the full notice is found. |
|
<one line to give the library's name and a brief idea of what it does.> |
Copyright (C) <year> <name of author> |
|
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Lesser General Public |
License as published by the Free Software Foundation; either |
version 2.1 of the License, or (at your option) any later version. |
|
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Lesser General Public License for more details. |
|
You should have received a copy of the GNU Lesser General Public |
License along with this library; if not, write to the Free Software |
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
|
Also add information on how to contact you by electronic and paper mail. |
|
You should also get your employer (if you work as a programmer) or your |
school, if any, to sign a "copyright disclaimer" for the library, if |
necessary. Here is a sample; alter the names: |
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the |
library `Frob' (a library for tweaking knobs) written by James Random Hacker. |
|
<signature of Ty Coon>, 1 April 1990 |
Ty Coon, President of Vice |
|
That's all there is to it! |
|
|