import serial
import struct
from time import sleep
class stm32_boot:
def __init__(self, port, baud=115200):
self.serial = serial.Serial(port, baud, 8, 'E', 1,
timeout=1)
self.serial.setDTR(1)
sleep(0.1)
self._sync()
def _sync(self):
self.serial.write(b"\x7f")
self._checkack()
def _sendcmd(self, cmd):
cmd = ord(cmd)
cmd = bytes((cmd, cmd ^ 0xff))
self.serial.write(cmd)
def _send(self, data):
csum = 0
for c in data: csum ^= c
data = data + bytes((csum,))
self.serial.write(data)
def _checkack(self):
ACK = b"\x79"
b = self.serial.read(1)
if b != ACK: raise Exception("Invalid ack: %r" % b)
def get(self):
self._sendcmd(b"\x00")
self._checkack()
num = self.serial.read(1)[0]
data = self.serial.read(num+1)
self._checkack()
return data
def eraseall(self):
self._sendcmd(b"\x43")
self._checkack()
self._sendcmd(b"\xff")
self._checkack()
def read(self, addr, len):
self._sendcmd(b"\x11")
self._checkack()
self._send(struct.pack(">L", addr))
self._checkack()
self._sendcmd(bytes((len-1,)))
self._checkack()
return self.serial.read(len)
def write(self, addr, data):
self._sendcmd(b"\x31")
self._checkack()
self._send(struct.pack(">L", addr))
self._checkack()
self._send(bytes((len(data)-1,)) + data)
self._checkack()
def write_protect(self, sectors):
self._sendcmd(b"\x63")
self._checkack()
self._send(bytes((len(sectors)-1,)) + bytes(sectors))
self._checkack()
self._sync()
def write_unprotect(self):
self._sendcmd(b"\x73")
self._checkack()
self._checkack()
self._sync()
def read_protect(self):
self._sendcmd(b"\x82")
self._checkack()
self._checkack()
self._sync()
def read_unprotect(self):
self._sendcmd(b"\x92")
self._checkack()
self._checkack()
self._sync()
if __name__ == "__main__":
from sys import stdout, argv, platform
from getopt import getopt
if platform == "linux":
print("\x1b\x5b\x48\x1b\x5b\x32\x4a") print("STM32 SystemMemory Production Programmer -- version 1.1")
print("Copyright (C) 2011 Black Sphere Technologies")
print("License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>")
print()
dev = "COM1" if platform == "win32" else "/dev/ttyUSB0"
baud = 115200
addr = 0x8000000
try:
opts, args = getopt(argv[1:], "b:d:a:")
for opt in opts:
if opt[0] == "-b": baud = int(opt[1])
elif opt[0] == "-d": dev = opt[1]
else: raise Exception()
progfile = args[0]
except:
print("Usage %s [-d <dev>] [-b <baudrate>] [-a <address>] <filename>" % argv[0])
print("\t-d : Use target on interface <dev> (default: %s)" % dev)
print("\t-b : Set device baudrate (default: %d)" % baud)
print("\t-a : Set programming address (default: 0x%X)" % addr)
print()
exit(-1)
prog = open(progfile, "rb").read()
boot = stm32_boot(dev, baud)
cmds = boot.get()
print("Target bootloader version: %d.%d\n" % (cmds[0] >> 4, cmds[0] % 0xf))
print("Removing device protection...")
boot.read_unprotect()
boot.write_unprotect()
print("Erasing target device...")
boot.eraseall()
addr = 0x8000000
while prog:
print("Programming address 0x%08X..0x%08X...\r" % (addr, addr + min(len(prog), 255)), end=' ')
stdout.flush()
boot.write(addr, prog[:256])
addr += 256
prog = prog[256:]
print
print("Enabling device protection...")
boot.write_protect(range(0,2))
print("All operations completed.")
print