#!/usr/bin/env python import optparse, os, sys, time # The binary file at [contiki]/tools/stm32w/stm32w_flasher/stm32w_flasher # contained python code. # This binary file did not work anymore on Ubuntu 12.04, so # it was replaced by this extracted python code, as discussed # with people at ST Crolles (France). # # Extraction and little adaptation performed by E.Duble (CNRS, LIG). try: import serial import ftdi import pyudev except: print 'Python modules serial, ftdi and pyudev could not be loaded.' print 'Please install these dependencies:' print '(On Ubuntu) $ sudo apt-get install python-serial python-ftdi python-pyudev' sys.exit(-1) from messages import infoMessage, errorMessage from rs232_interface import rs232Interface, getFirstAvailableSerialPort versionMajor = 2 versionMinor = 0 versionPatch = 1 versionQualifier = "b2" version = "%d.%d.%d%s"%(versionMajor, versionMinor, versionPatch, versionQualifier) commandTable = [ ['-i', '--interface', 'store', " specify flasher interface (default rs232)",None], ['-p', '--port', 'store', ": specify rs232 port or auto mode (only relevant if interface selected is rs232 or rf)", None], ['-f', '--flash-image', 'store_true', "program flash"], ['-a', '--address', 'store', "0xHHHHHHHH specify baseaddress (only relevat for .bin images)", "0x08000000"], ['-v', '--verify', 'store_true', "verify flash content against file", False], #['-d', '--device-info', 'store_true', 'print information about the STM32W device', False], ['-r', '--reset', 'store_true', 'Reset device', False], ['-s', '--start', 'store_true', 'Start application', False], ['-m', '--masserase', 'store_true', 'Erase user flash (masserase)', False], ['-b', '--bootloader-mode', 'store_true', 'Device is already in bootloader mode.(Only relevant for rs232 interface)', False], ['-e', '--eui64', 'store', "0xHHHHHHHHHHHHHHHH specify EUI64 (only relevat for rf interface)", "0xFFFFFFFFFFFFFFFF"], ['', '--enable-readout-protection', 'store', "<0|1> Disable or enable readout protection", None], ['', '--set-write-protection', 'store', "0xHHHHHHHH Set write protection to hex value (each bit set to zero is protecting 4K)" , "0xFFFFFFFF"], ] def initCommandLineParser(): """Create a command-line parser and return it. """ USAGE = '%prog [option...] [filename{.s37|.bin}] ...' DESCR = """ Flash programming utility for STM32W108 device """ parser = optparse.OptionParser(usage=USAGE, description=DESCR, version='%%prog %s' % version) for item in commandTable: if len(item) > 4: default = item[4] else: default = None parser.add_option(item[0], item[1], action=item[2], help=item[3], default=default) return parser def getFileVersionDate(fname): returnValue = "" return returnValue def initInterface (interface, port, noReset=False, rfMode=False, eui64=0): returnValue = rs232Interface(port, noReset, rfMode, eui64) if returnValue.init(): returnValue = None return returnValue def terminateInterface(interface): if (isinstance(interface, rs232Interface)): interface.terminate() def flashImage (interface, inputFile, startAddress, doErase=True): def progressReport(size, fileSize): infoMessage ("Programming %05d/%05d\r"%(size,fileSize)) infoMessage ("Programming user flash\n") if not interface.programUserFlash(inputFile, startAddress, progressReport, doErase): infoMessage("Failed \n") else: infoMessage("Done \n") def verifyFlashImage (interface, inputFile, startAddress): def progressReport(size, fileSize): infoMessage ("Verifying %05d/%05d\r"%(size,fileSize)) infoMessage ("Verifying user flash\n") if not interface.verifyFlash(inputFile, startAddress, progressReport): infoMessage("Failed \n") else: infoMessage("Done \n") def resetDevice (interface): infoMessage ("Resetting device\n") returnValue = not interface.startApplication(0) if (returnValue): infoMessage("Failed \n") else: infoMessage("Done \n") def startApplication (interface, startAddress): infoMessage ("Starting application from address: %08x\n"%startAddress) if not interface.startApplication(startAddress): infoMessage("Failed \n") else: infoMessage("Done \n") def eraseUserFlash (interface): infoMessage ("Erasing user flash (mass erase)\n") if not interface.eraseUserFlash(): infoMessage("Failed \n") else: infoMessage("Done \n") def printBanner(): infoMessage ("STM32W flasher utility version %s\n"%version) if __name__ == '__main__': try: absolutePath = os.path.abspath(sys.argv[0]) if "frozen" in dir(sys): version += " " + getFileVersionDate(sys.executable) else: version += "-" + time.strftime("%Y%m%d",time.localtime(os.stat(absolutePath).st_ctime)) version += " for Linux" interfaceHandle = None printBanner() parser = initCommandLineParser() (options, args) = parser.parse_args() rfMode = False # Check command line option if (len(args) == 1): if (len(sys.argv) == 2): # No option means flashing by default options.flash_image = True options.image = args[0] if (len(args) > 1): parser.print_help() sys.exit(-1) if (len(sys.argv) == 1): parser.print_help() sys.exit(0) if (options.interface is None): # Set defualt for interface if (options.port is None): options.interface = "rs232" options.port = "auto" else: options.interface = "rs232" elif (options.interface == "rf"): rfMode = True options.address = "0x08003000" options.interface = "rs232" options.bootloader_mode = True options.interface = options.interface.lower() if ((options.interface == "rs232") and (options.port == None)): parser.print_help() sys.exit(-1) if (options.interface != "rs232" and options.interface != "jlink"): parser.print_help() sys.exit(-1) startAddress = int(options.address,16) if (options.interface == "rs232"): optionArg = options.port.upper() if (optionArg == "AUTO"): port = getFirstAvailableSerialPort() if port is None: errorMessage ("Unable to find serial port in auto mode: no STM32W boards detected\n") sys.exit(-1) infoMessage ("Auto mode selected serial port: %s\n"%port) elif (options.port[:4] == "/dev"): ## For Linux port = options.port else: try: port = int(optionArg) except ValueError: errorMessage("Invalid port: %s\n"%options.port) sys.exit(-1) else: port = None if (options.interface == "jlink"): errorMessage("JLink not yet supported.\n") sys.exit(-1) if (options.start and options.reset): errorMessage ("Only one option between -s (--start) and -r (--reset) may be specified") sys.exit(-1) interfaceHandle = initInterface(options.interface, port, options.bootloader_mode, rfMode, int(options.eui64, 16)) if interfaceHandle is None: errorMessage("Error while initiliazing interface\n") sys.exit(-1) readoutProtection = interfaceHandle.isReadProtectionActive() if readoutProtection: infoMessage("!Warning: Readout protection is active\n") options.device_info = False if (options.masserase): eraseUserFlash(interfaceHandle) if (options.enable_readout_protection is not None): if (options.enable_readout_protection == "1"): if not readoutProtection: infoMessage("Enabling readout protection\n") interfaceHandle.enableReadProtection(True) infoMessage("Done\n") else: infoMessage("Readout protection already enabled, no action\n") elif (options.enable_readout_protection == "0"): if readoutProtection: infoMessage("Disabling readout protection (this will clear user flash and CIB)\n") interfaceHandle.enableReadProtection(False) infoMessage("Done\n") else: infoMessage("Readout protection already disaabled, no action\n") else: errorMessage("Invalid value for --enable-readout-protection\n") terminateInterface(interfaceHandle) sys.exit(-1) if options.flash_image: flashImage(interfaceHandle, options.image, startAddress, not options.masserase) if options.verify and not readoutProtection: verifyFlashImage(interfaceHandle, options.image, startAddress) if (options.start): startApplication(interfaceHandle, startAddress) if (options.reset): resetDevice(interfaceHandle) terminateInterface(interfaceHandle) sys.exit (0) except KeyboardInterrupt: infoMessage ("User break\n") terminateInterface(interfaceHandle) sys.exit(-1) except Exception, inst: if not ("frozen" in dir(sys)): raise else: errorMessage("Internal error\n") errorMessage("%s\n"%repr(type(inst))) # the exception instance errorMessage("%s\n"%repr(inst.args)) # arguments stored in .args if interfaceHandle: terminateInterface(interfaceHandle) sys.exit(-1)