From 0d8fc2912fb01cdbd01b38d1ae37b2073e6447da Mon Sep 17 00:00:00 2001 From: Domen Puncer Date: Mon, 18 Jun 2012 10:37:36 +0200 Subject: [PATCH 1/6] Fix unclear comments on serial setup --- stm32loader/stm32loader.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stm32loader/stm32loader.py b/stm32loader/stm32loader.py index 67e3b6f..f7c7796 100755 --- a/stm32loader/stm32loader.py +++ b/stm32loader/stm32loader.py @@ -51,8 +51,8 @@ class CommandInterface: bytesize=8, # number of databits parity=serial.PARITY_EVEN, stopbits=1, - xonxoff=0, # enable software flow control - rtscts=0, # disable RTS/CTS flow control + xonxoff=0, # don't enable software flow control + rtscts=0, # don't enable RTS/CTS flow control timeout=5 # set a timeout value, None for waiting forever ) From e502858e6aee04452f6b5d1969d1a213690e97bf Mon Sep 17 00:00:00 2001 From: Domen Puncer Date: Mon, 18 Jun 2012 10:40:43 +0200 Subject: [PATCH 2/6] Open file in binary mode, so it works on windows. Fix from http://www.micromouseonline.com/2009/05/08/stm32-arm-cortex-bootloader/#comment-197 --- stm32loader/stm32loader.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stm32loader/stm32loader.py b/stm32loader/stm32loader.py index f7c7796..4a903b6 100755 --- a/stm32loader/stm32loader.py +++ b/stm32loader/stm32loader.py @@ -402,7 +402,7 @@ if __name__ == "__main__": # cmd.cmdWriteProtect([0, 1]) if (conf['write'] or conf['verify']): - data = map(lambda c: ord(c), file(args[0]).read()) + data = map(lambda c: ord(c), file(args[0], 'rb').read()) if conf['erase']: cmd.cmdEraseMemory() From b72acb9cd7358b420bfab0ed107005c8142c6344 Mon Sep 17 00:00:00 2001 From: Domen Puncer Date: Mon, 18 Jun 2012 11:12:39 +0200 Subject: [PATCH 3/6] fix "Unknow" typo --- stm32loader/stm32loader.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stm32loader/stm32loader.py b/stm32loader/stm32loader.py index 4a903b6..123a1bb 100755 --- a/stm32loader/stm32loader.py +++ b/stm32loader/stm32loader.py @@ -72,8 +72,8 @@ class CommandInterface: # NACK raise CmdException("NACK "+info) else: - # Unknow responce - raise CmdException("Unknow response. "+info+": "+hex(ask)) + # Unknown responce + raise CmdException("Unknown response. "+info+": "+hex(ask)) def reset(self): From 15db5e2e8ad908395377c41cef8b230b2d256fd5 Mon Sep 17 00:00:00 2001 From: Domen Puncer Date: Mon, 18 Jun 2012 11:31:03 +0200 Subject: [PATCH 4/6] Added extended erase (0x44), needed for stm32f2 stm32f4 series --- stm32loader/stm32loader.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/stm32loader/stm32loader.py b/stm32loader/stm32loader.py index 123a1bb..ba4ad98 100755 --- a/stm32loader/stm32loader.py +++ b/stm32loader/stm32loader.py @@ -44,6 +44,8 @@ class CmdException(Exception): pass class CommandInterface: + extended_erase = 0 + def open(self, aport='/dev/tty.usbserial-ftCYPMYJ', abaudrate=115200) : self.sp = serial.Serial( port=aport, @@ -106,6 +108,8 @@ class CommandInterface: version = ord(self.sp.read()) mdebug(10, " Bootloader version: "+hex(version)) dat = map(lambda c: hex(ord(c)), self.sp.read(len)) + if '0x44' in dat: + self.extended_erase = 1 mdebug(10, " Available commands: "+str(dat)) self._wait_for_ask("0x00 end") return version @@ -189,6 +193,9 @@ class CommandInterface: def cmdEraseMemory(self, sectors = None): + if self.extended_erase: + return cmd.cmdExtendedEraseMemory() + if self.cmdGeneric(0x43): mdebug(10, "*** Erase memory command") if sectors is None: @@ -208,6 +215,23 @@ class CommandInterface: else: raise CmdException("Erase memory (0x43) failed") + 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)) + # Checksum + self.sp.write(chr(0x00)) + tmp = self.sp.timeout + self.sp.timeout = 30 + 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") From aa21cfd79d6f6b023a74bc750311b221bc0651c8 Mon Sep 17 00:00:00 2001 From: Domen Puncer Date: Tue, 19 Jun 2012 15:06:39 +0200 Subject: [PATCH 5/6] Bootloader command GO, -g --- stm32loader/stm32loader.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/stm32loader/stm32loader.py b/stm32loader/stm32loader.py index ba4ad98..d6b0b3c 100755 --- a/stm32loader/stm32loader.py +++ b/stm32loader/stm32loader.py @@ -329,7 +329,7 @@ class CommandInterface: def usage(): - print """Usage: %s [-hqVewvr] [-l length] [-p port] [-b baud] [-a 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 @@ -341,6 +341,7 @@ def usage(): -p port Serial port (default: /dev/tty.usbserial-ftCYPMYJ) -b baud Baud speed (default: 115200) -a addr Target address + -g addr Address to start running at (0x08000000, usually) ./stm32loader.py -e -w -v example/main.bin @@ -365,12 +366,13 @@ if __name__ == "__main__": 'write': 0, 'verify': 0, 'read': 0, + 'go_addr':-1, } # http://www.python.org/doc/2.5.2/lib/module-getopt.html try: - opts, args = getopt.getopt(sys.argv[1:], "hqVewvrp:b:a:l:") + opts, args = getopt.getopt(sys.argv[1:], "hqVewvrp:b:a:l:g:") except getopt.GetoptError, err: # print help information and exit: print str(err) # will print something like "option -a not recognized" @@ -401,6 +403,8 @@ if __name__ == "__main__": conf['baud'] = eval(a) elif o == '-a': conf['address'] = eval(a) + elif o == '-g': + conf['go_addr'] = eval(a) elif o == '-l': conf['len'] = eval(a) else: @@ -449,7 +453,9 @@ if __name__ == "__main__": rdata = cmd.readMemory(conf['address'], conf['len']) file(args[0], 'wb').write(''.join(map(chr,rdata))) -# cmd.cmdGo(addr + 0x04) + if conf['go_addr'] != -1: + cmd.cmdGo(conf['go_addr']) + finally: cmd.releaseChip() From 0d5b49b5c3f8d586328e28a09f22e2558b07dfd5 Mon Sep 17 00:00:00 2001 From: Domen Puncer Date: Tue, 19 Jun 2012 16:28:47 +0200 Subject: [PATCH 6/6] Add chip id strings --- stm32loader/stm32loader.py | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/stm32loader/stm32loader.py b/stm32loader/stm32loader.py index d6b0b3c..95adc05 100755 --- a/stm32loader/stm32loader.py +++ b/stm32loader/stm32loader.py @@ -35,6 +35,19 @@ except: # Verbose level QUIET = 20 +# these come from AN2606 +chip_ids = { + 0x412: "STM32 Low-density", + 0x410: "STM32 Medium-density", + 0x414: "STM32 High-density", + 0x420: "STM32 Medium-density value line", + 0x428: "STM32 High-density value line", + 0x430: "STM32 XL-density", + 0x416: "STM32 Medium-density ultralow power line", + 0x411: "STM32F2xx", + 0x413: "STM32F4xx", +} + def mdebug(level, message): if(QUIET >= level): print >> sys.stderr , message @@ -110,7 +123,7 @@ class CommandInterface: dat = map(lambda c: hex(ord(c)), self.sp.read(len)) if '0x44' in dat: self.extended_erase = 1 - mdebug(10, " Available commands: "+str(dat)) + mdebug(10, " Available commands: "+", ".join(dat)) self._wait_for_ask("0x00 end") return version else: @@ -133,7 +146,7 @@ class CommandInterface: len = ord(self.sp.read()) id = self.sp.read(len+1) self._wait_for_ask("0x02 end") - return id + return reduce(lambda x, y: x*0x100+y, map(ord, id)) else: raise CmdException("GetID (0x02) failed") @@ -422,7 +435,8 @@ if __name__ == "__main__": bootversion = cmd.cmdGet() mdebug(0, "Bootloader version %X" % bootversion) - mdebug(0, "Chip id `%s'" % str(map(lambda c: hex(ord(c)), cmd.cmdGetID()))) + id = cmd.cmdGetID() + mdebug(0, "Chip id: 0x%x (%s)" % (id, chip_ids.get(id, "Unknown"))) # cmd.cmdGetVersion() # cmd.cmdGetID() # cmd.cmdReadoutUnprotect()