From 940d7bbefa56a0008882147ca268726d78d174af Mon Sep 17 00:00:00 2001 From: Majid Lotfi Date: Tue, 30 Sep 2025 21:31:27 +0330 Subject: [PATCH] Fix: Python3 compatible version --- stm32loader.py | 105 ++++++++++++++++++++++++++----------------------- 1 file changed, 56 insertions(+), 49 deletions(-) diff --git a/stm32loader.py b/stm32loader.py index 95adc05..1f1b49e 100755 --- a/stm32loader.py +++ b/stm32loader.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # -*- coding: utf-8 -*- # vim: sw=4:ts=4:si:et:enc=utf-8 @@ -25,6 +25,8 @@ import sys, getopt import serial import time +from functools import reduce # add this at the top + try: from progressbar import * @@ -50,7 +52,7 @@ def mdebug(level, message): if(QUIET >= level): - print >> sys.stderr , message + print(message, file=sys.stderr) class CmdException(Exception): @@ -59,7 +61,7 @@ class CmdException(Exception): class CommandInterface: extended_erase = 0 - def open(self, aport='/dev/tty.usbserial-ftCYPMYJ', abaudrate=115200) : + def open(self, aport='/dev/ttyUSB0', abaudrate=115200) : self.sp = serial.Serial( port=aport, baudrate=abaudrate, # baudrate @@ -75,7 +77,10 @@ def open(self, aport='/dev/tty.usbserial-ftCYPMYJ', abaudrate=115200) : def _wait_for_ask(self, info = ""): # wait for ask try: - ask = ord(self.sp.read()) + data = self.sp.read(1) + if not data: + raise CmdException("Can't read port or timeout") + ask = data[0] except: raise CmdException("Can't read port or timeout") else: @@ -102,7 +107,7 @@ def initChip(self): self.sp.setRTS(0) self.reset() - self.sp.write("\x7F") # Syncro + self.sp.write(b"\x7F") # Syncro return self._wait_for_ask("Syncro") def releaseChip(self): @@ -110,17 +115,17 @@ def releaseChip(self): self.reset() def cmdGeneric(self, cmd): - self.sp.write(chr(cmd)) - self.sp.write(chr(cmd ^ 0xFF)) # Control byte + self.sp.write(bytes([cmd])) + self.sp.write(bytes([cmd ^ 0xFF])) # Control byte return self._wait_for_ask(hex(cmd)) def cmdGet(self): if self.cmdGeneric(0x00): mdebug(10, "*** Get command"); - len = ord(self.sp.read()) - version = ord(self.sp.read()) + len = self.sp.read()[0] + version = self.sp.read()[0] mdebug(10, " Bootloader version: "+hex(version)) - dat = map(lambda c: hex(ord(c)), self.sp.read(len)) + dat = list(map(lambda c: hex(c), self.sp.read(len))) if '0x44' in dat: self.extended_erase = 1 mdebug(10, " Available commands: "+", ".join(dat)) @@ -132,7 +137,7 @@ def cmdGet(self): def cmdGetVersion(self): if self.cmdGeneric(0x01): mdebug(10, "*** GetVersion command") - version = ord(self.sp.read()) + version = self.sp.read()[0] self.sp.read(2) self._wait_for_ask("0x01 end") mdebug(10, " Bootloader version: "+hex(version)) @@ -143,21 +148,21 @@ def cmdGetVersion(self): def cmdGetID(self): if self.cmdGeneric(0x02): mdebug(10, "*** GetID command") - len = ord(self.sp.read()) - id = self.sp.read(len+1) + length = self.sp.read()[0] + id_bytes = self.sp.read(length + 1) self._wait_for_ask("0x02 end") - return reduce(lambda x, y: x*0x100+y, map(ord, id)) + # Python 3: bytes are already ints, no need for ord() + return reduce(lambda x, y: x*0x100 + y, id_bytes) else: raise CmdException("GetID (0x02) failed") - def _encode_addr(self, addr): byte3 = (addr >> 0) & 0xFF byte2 = (addr >> 8) & 0xFF byte1 = (addr >> 16) & 0xFF byte0 = (addr >> 24) & 0xFF crc = byte0 ^ byte1 ^ byte2 ^ byte3 - return (chr(byte0) + chr(byte1) + chr(byte2) + chr(byte3) + chr(crc)) + return bytes([byte0, byte1, byte2, byte3, crc]) def cmdReadMemory(self, addr, lng): @@ -168,9 +173,9 @@ def cmdReadMemory(self, addr, lng): self._wait_for_ask("0x11 address failed") N = (lng - 1) & 0xFF crc = N ^ 0xFF - self.sp.write(chr(N) + chr(crc)) + self.sp.write(bytes([N, crc])) self._wait_for_ask("0x11 length failed") - return map(lambda c: ord(c), self.sp.read(lng)) + return list(map(lambda c: c, self.sp.read(lng))) # or keep the ord if needed else: raise CmdException("ReadMemory (0x11) failed") @@ -193,12 +198,12 @@ def cmdWriteMemory(self, addr, data): #map(lambda c: hex(ord(c)), data) lng = (len(data)-1) & 0xFF mdebug(10, " %s bytes to write" % [lng+1]); - self.sp.write(chr(lng)) # len really + self.sp.write(bytes([lng])) # len really crc = 0xFF for c in data: crc = crc ^ c - self.sp.write(chr(c)) - self.sp.write(chr(crc)) + self.sp.write(bytes([c])) + self.sp.write(bytes([crc])) self._wait_for_ask("0x31 programming failed") mdebug(10, " Write memory done") else: @@ -213,16 +218,16 @@ def cmdEraseMemory(self, sectors = None): mdebug(10, "*** Erase memory command") if sectors is None: # Global erase - self.sp.write(chr(0xFF)) - self.sp.write(chr(0x00)) + self.sp.write(bytes([0xFF])) + self.sp.write(bytes([0x00])) else: # Sectors erase - self.sp.write(chr((len(sectors)-1) & 0xFF)) + self.sp.write(bytes([(len(sectors)-1) & 0xFF])) crc = 0xFF for c in sectors: crc = crc ^ c - self.sp.write(chr(c)) - self.sp.write(chr(crc)) + self.sp.write(bytes([c])) + self.sp.write(bytes([crc])) self._wait_for_ask("0x43 erasing failed") mdebug(10, " Erase memory done") else: @@ -232,28 +237,29 @@ def cmdExtendedEraseMemory(self): if self.cmdGeneric(0x44): mdebug(10, "*** Extended Erase memory command") # Global mass erase - self.sp.write(chr(0xFF)) - self.sp.write(chr(0xFF)) + self.sp.write(bytes([0xFF])) + self.sp.write(bytes([0xFF])) # Checksum - self.sp.write(chr(0x00)) + self.sp.write(bytes([0x00])) tmp = self.sp.timeout self.sp.timeout = 30 - print "Extended erase (0x44), this can take ten seconds or more" + print("Extended erase (0x44), this can take ten seconds or more") self._wait_for_ask("0x44 erasing failed") self.sp.timeout = tmp mdebug(10, " Extended Erase memory done") else: raise CmdException("Extended Erase memory (0x44) failed") + def cmdWriteProtect(self, sectors): if self.cmdGeneric(0x63): mdebug(10, "*** Write protect command") - self.sp.write(chr((len(sectors)-1) & 0xFF)) + self.sp.write(bytes([(len(sectors)-1) & 0xFF])) crc = 0xFF for c in sectors: crc = crc ^ c - self.sp.write(chr(c)) - self.sp.write(chr(crc)) + self.sp.write(bytes([c])) + self.sp.write(bytes([crc])) self._wait_for_ask("0x63 write protect failed") mdebug(10, " Write protect done") else: @@ -294,7 +300,7 @@ def readMemory(self, addr, lng): if usepbar: widgets = ['Reading: ', Percentage(),', ', ETA(), ' ', Bar()] pbar = ProgressBar(widgets=widgets,maxval=lng, term_width=79).start() - + while lng > 256: if usepbar: pbar.update(pbar.maxval-lng) @@ -316,7 +322,7 @@ def writeMemory(self, addr, data): if usepbar: widgets = ['Writing: ', Percentage(),' ', ETA(), ' ', Bar()] pbar = ProgressBar(widgets=widgets, maxval=lng, term_width=79).start() - + offs = 0 while lng > 256: if usepbar: @@ -337,12 +343,12 @@ def writeMemory(self, addr, data): - def __init__(self) : + def __init__(self): pass def usage(): - print """Usage: %s [-hqVewvr] [-l length] [-p port] [-b baud] [-a addr] [-g addr] [file.bin] + print("""Usage: %s [-hqVewvr] [-l length] [-p port] [-b baud] [-a addr] [-g addr] [file.bin] -h This help -q Quiet -V Verbose @@ -358,21 +364,21 @@ def usage(): ./stm32loader.py -e -w -v example/main.bin - """ % sys.argv[0] + """ % sys.argv[0]) if __name__ == "__main__": - + # Import Psyco if available try: import psyco psyco.full() - print "Using Psyco..." + print("Using Psyco...") except ImportError: pass conf = { - 'port': '/dev/tty.usbserial-ftCYPMYJ', + 'port': '/dev/ttyUSB0', 'baud': 115200, 'address': 0x08000000, 'erase': 0, @@ -386,9 +392,9 @@ def usage(): try: opts, args = getopt.getopt(sys.argv[1:], "hqVewvrp:b:a:l:g:") - except getopt.GetoptError, err: + except getopt.GetoptError as err: # print help information and exit: - print str(err) # will print something like "option -a not recognized" + print(str(err)) # will print something like "option -a not recognized" usage() sys.exit(2) @@ -430,7 +436,7 @@ def usage(): try: cmd.initChip() except: - print "Can't init. Ensure that BOOT0 is enabled and reset device" + print("Can't init. Ensure that BOOT0 is enabled and reset device") bootversion = cmd.cmdGet() @@ -444,10 +450,11 @@ def usage(): # cmd.cmdWriteProtect([0, 1]) if (conf['write'] or conf['verify']): - data = map(lambda c: ord(c), file(args[0], 'rb').read()) + data = list(map(lambda c: c, open(args[0], 'rb').read())) if conf['erase']: cmd.cmdEraseMemory() + time.sleep(0.5) if conf['write']: cmd.writeMemory(conf['address'], data) @@ -455,13 +462,13 @@ def usage(): if conf['verify']: verify = cmd.readMemory(conf['address'], len(data)) if(data == verify): - print "Verification OK" + print("Verification OK") else: - print "Verification FAILED" - print str(len(data)) + ' vs ' + str(len(verify)) + print("Verification FAILED") + print(str(len(data)) + ' vs ' + str(len(verify))) for i in xrange(0, len(data)): if data[i] != verify[i]: - print hex(i) + ': ' + hex(data[i]) + ' vs ' + hex(verify[i]) + print(hex(i) + ': ' + hex(data[i]) + ' vs ' + hex(verify[i])) if not conf['write'] and conf['read']: rdata = cmd.readMemory(conf['address'], conf['len'])