Mam trochę ostatnio męczę port szeregowy w pythonie, ale mam problem z przeportowaniem programu do systemu Windows, bo jednak większość PC ma zainstalowany ten właśnie system. Problemem jest wykorzystywanie bibliteki posix-a, tty oraz fcntl.
Programować w pythonie dopiero zaczynam, więc nie potrafię przenieść tego programu, aby nie korzystały z tych bibliotek.
Kod: Zaznacz cały
import fcntl, posix, re, string, sys, termios, tty, serial
class ssbl:
avr = None
pagesize = 64
oldattrs = None
def open(self, dev, baud=termios.B9600):
t = termios
self.avr = posix.open('/dev/ttyUSB0', posix.O_RDWR | posix.O_NOCTTY)
t.tcflush(self.avr, t.TCIOFLUSH)
attrs = t.tcgetattr(self.avr)
nattrs = [
( attrs[0] & ~(t.BRKINT | t.ICRNL | t.INPCK | t.IXON | t.IXOFF)) | t.ICRNL | t.ISTRIP,
attrs[1] & ~(t.OPOST),
( attrs[2] & ~(t.CSIZE | t.PARENB | t.CRTSCTS) ) | t.CS8 | t.CLOCAL | t.CREAD,
attrs[3] & ~(t.ECHO | t.ICANON | t.IEXTEN | t.ISIG),
baud, baud,
attrs[6][:]
] + attrs[7:]
nattrs[6][t.VMIN] = 0
nattrs[6][t.VTIME] = 10
self.oldattrs = attrs
t.tcsetattr(self.avr, t.TCSAFLUSH, nattrs)
def close(self):
if self.avr is not None:
if self.oldattrs is not None:
t.tcsetattr(self.avr, t.TCSAFLUSH)
posix.close(self.avr)
self.avr = None
def __del__(self):
if self.avr is not None:
posix.close(self.avr)
self.avr = None
def do(self, cmd, rbuflen=64):
n = posix.write(self.avr, cmd)
if (n < len(cmd)):
raise e, 'Failed to write cmd'
s = posix.read(self.avr, rbuflen)
if s == '':
raise e, 'Timed out waiting response'
if s == '?':
raise e, 'Command not supported'
buf = s
while '\r' not in buf and '\n' not in buf:
s = posix.read(self.avr, rbuflen)
if s == '':
raise e, 'Timed out awaiting rest of response'
buf = buf + s
return buf
def pagewrite(self, addr, data):
setz = 'z%04X' % (addr,)
self.do(setz)
dlen = len(data)
if dlen == 0:
return
if (dlen % 2) != 0:
raise e, 'Must write a whole number of words'
self.do('P000003') # erase page
self.do('P000011') # enable read-while-write (why necc.?)
self.do('Q')
words = dlen / 2
self.do('W%02X' % (words,) +
string.join(map(lambda x: '%02X' % (ord(x),), data),''))
self.do('Q')
self.do(setz)
self.do('P000005') # write page
self.do('P000011') # enable read-while-write (why necc.?)
self.do('Q')
def readmem(self, addr, nbytes):
self.do('z%04X' % (addr,))
b = self.do('R%02X' % (nbytes,)).strip()
buf = ''
for i in range(0, len(b), 2):
buf = buf + chr(int(b[i:i+2],16))
return buf
def read_ihex(f):
memory = {}
for line in f:
line = line.strip()
if not line.startswith(":"): continue
bytecount = int(line[1:3], 16)
address = int(line[3:7], 16)
rectype = int(line[7:9], 16)
data = line[9:-2]
checksum = int(line[-2:], 16)
if 2 * bytecount != len(data):
raise error, "Bad byte count (%dd/%dx) in ihex record" % (bytecount,len(data))
check = sum(map(lambda i: int(line[i:i+2],16), range(1, len(line), 2)))
if check % 256 != 0:
raise error, "bad checksum in ihex record (0x%x)" % check
if rectype > 1:
raise error, "Unsupported record type 0x%02x" % rectype
if rectype == 1:
break
for i in range(address, address + len(data)/2):
j = 2 * (i - address)
memory[i] = int(data[j:j+2], 16)
l = [-1] * (max(memory.keys()) + 1)
for k, v in memory.items(): l[k] = v
return l
def writeall(avr, memmap, precheck=0, dots=1):
if dots:
sys.stdout.write("Zapis")
for addr in range(0, len(memmap), avr.pagesize):
page = memmap[addr : addr+avr.pagesize]
if page == ( [-1] * len(page) ):
continue
if len(page) < avr.pagesize:
page = page + ( [-1] * (avr.pagesize * len(page)) )
if precheck or (-1 in page):
old = avr.readmem(addr, avr.pagesize)
buf = ''
for subaddr in range(0, avr.pagesize):
if page[subaddr] != -1:
buf = buf + chr(page[subaddr])
else:
buf = buf + old[subaddr]
if old == buf:
if dots:
sys.stdout.write('.')
else:
avr.pagewrite(addr, buf)
if dots:
sys.stdout.write('#')
if dots:
sys.stdout.flush()
if dots:
sys.stdout.write("\n")
def verify(avr, memmap, dots=1):
if dots:
sys.stdout.write("Weryfikacja")
for addr in range(0, len(memmap), avr.pagesize):
page = memmap[addr : addr+avr.pagesize]
if page == ( [-1] * len(page) ):
continue
if len(page) < avr.pagesize:
page = page + ( [-1] * (avr.pagesize * len(page)) )
buf = avr.readmem(addr, avr.pagesize)
for subaddr in range(0, avr.pagesize):
if page[subaddr] != -1:
rd = ord(buf[subaddr])
if rd != page[subaddr]:
print "Mismatch at address %04x: read %02x, want %02x" % (addr+subaddr, rd, page[subaddr])
if dots:
sys.stdout.write('.')
sys.stdout.flush()
if dots:
sys.stdout.write("\n")
def progify(filename):
M = read_ihex(open(filename))
a = ssbl()
a.verbose = 1
a.open('/dev/ttyUSB0')
a.do('Q')
a.verbose = 0
writeall(a, M, dots=1, precheck=1)
verify(a, M, dots=1)
a.do('z0000')
posix.write(a.avr, '@')
a.close
progify('usbasp.hex')