def _getPasswordFromFile(filename): '''从文件获得密码,做一层缓存以加快效率''' global __PASSWORD_FILE_MAP if filename is None: return "\xFF"*32 if filename in __PASSWORD_FILE_MAP: return __PASSWORD_FILE_MAP[filename] passwd = memory.load(filename).get_range(0xffe0, 0xffff) __PASSWORD_FILE_MAP[filename] = passwd return passwd
def download_ver(self, old_file_path=None, new_file_path=None, mass_erase=False): self.forward_and_check("BSL\r\n", "BSLOK") self.serial.baudrate = 9600 self.serial.parity = serial.PARITY_EVEN self.serial.timeout = 1 try: download_data = memory.Memory() # prepare downloaded data data = memory.load(new_file_path) download_data.merge(data) self.start_bsl() if mass_erase: self.bsl_mass_erase() print "Mass Erase Success!\r\n" passwd = _getPasswordFromFile(old_file_path) self.BSL_RX_PASSWORD(passwd) self.set_baudrate(115200) for segment in download_data: print "Write segment at 0x%04x %d bytes\n" % (segment.startaddress, len(segment.data)) uiLog(u"版本信息正在写入位置: 0x%04x %d bytes"%(segment.startaddress, len(segment.data))) data = segment.data if len(data) & 1: data += '\xff' self.memory_write(segment.startaddress, data) print "version downloaded successfully, starting read and verification." uiLog(u"版本写入完成,正在校验...") #读回版本并验证 for segment in download_data: sg = self.memory_read(segment.startaddress, len(segment.data)) #这是bytearray对象 if sg != segment.data: raise print "verify %2.X OK"%segment.startaddress uiLog(u'版本校验成功') except Exception as e: print "Program fail! " + str(e) superUiLog("Program fail! " + str(e)) raise e else: print "Program OK!" finally: self.quit_bsl() self.quit_bsl() print "quit bsl" superUiLog("quite bsl") self.serial.baudrate = 115200 self.serial.parity = serial.PARITY_NONE self.serial.timeout = 5 self.set_TEST(False)
def getDCOFreq(dcoctl, bcsctl1, bcsctl2=0): """\ Measure DCO frequency on a F1xx or F2xx device. return: frequency in Hz """ funclet = memory.load('counter', cStringIO.StringIO(COUNTER_FUNCLET), format='titext') funclet[0].data = funclet[0].data[:6] \ + chr(dcoctl) + chr(bcsctl1) + chr(bcsctl2) \ + funclet[0].data[9:] runtime = jtag._parjtag.funclet(funclet[0].data, 100) count = jtag._parjtag.regread(14) | (jtag._parjtag.regread(15) << 16) return 1000*count*4/runtime
def getDCOPlusFreq(scfi0, scfi1, scfqctl, fll_ctl0, fll_ctl1): """\ Measure DCO frequency on a F4xx device return: frequency in Hz. """ funclet = memory.load("counter", cStringIO.StringIO(COUNTERPLUS_FUNCLET), format='titext') funclet[0].data = funclet[0].data[:6] \ + chr(scfi0) + chr(scfi1) \ + chr(scfqctl) + chr(fll_ctl0) \ + chr(fll_ctl1) + funclet[0].data[11:] #~ funclet..[0x205] = scfi0, scfi1, scfqctl, fll_ctl0, fll_ctl1 runtime = jtag._parjtag.funclet(funclet[0].data, 100) count = jtag._parjtag.regread(14) | (jtag._parjtag.regread(15) << 16) return 1000*count*4/runtime
def getDCOFreq(dcoctl, bcsctl1, bcsctl2=0): """\ Measure DCO frequency on a F1xx or F2xx device. return: frequency in Hz """ funclet = memory.load('counter', BytesIO(COUNTER_FUNCLET), format='titext') funclet[0].data = funclet[0].data[:6] \ + chr(dcoctl) + chr(bcsctl1) + chr(bcsctl2) \ + funclet[0].data[9:] runtime = jtag._parjtag.funclet(funclet[0].data, 100) count = jtag._parjtag.regread(14) | (jtag._parjtag.regread(15) << 16) return 1000 * count * 4 / runtime
def getDCOPlusFreq(scfi0, scfi1, scfqctl, fll_ctl0, fll_ctl1): """\ Measure DCO frequency on a F4xx device return: frequency in Hz. """ funclet = memory.load('counter', BytesIO(COUNTERPLUS_FUNCLET), format='titext') funclet[0].data = funclet[0].data[:6] \ + chr(scfi0) + chr(scfi1) \ + chr(scfqctl) + chr(fll_ctl0) \ + chr(fll_ctl1) + funclet[0].data[11:] #~ funclet..[0x205] = scfi0, scfi1, scfqctl, fll_ctl0, fll_ctl1 runtime = jtag._parjtag.funclet(funclet[0].data, 100) count = jtag._parjtag.regread(14) | (jtag._parjtag.regread(15) << 16) return 1000 * count * 4 / runtime
# prepare output if self.options.output is None: self.output = sys.stdout if sys.platform == "win32": # ensure that the console is in binary mode import os, msvcrt msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY) else: self.output = open(self.options.output, 'wb') # prepare data to download / load files self.download_data = memory.Memory() # prepare downloaded data for filename in self.args: if filename == '-': data = memory.load( '<stdin>', sys.stdin, format=self.options.input_format or "titext") else: data = memory.load( filename, format=self.options.input_format) self.download_data.merge(data) def do_the_work(self): """\ Do the actual work, such as upload and download. """ # debug messages if self.verbose > 1: # show a nice list of scheduled actions
def main(): global DEBUG import getopt filetype = None filename = None comPort = 0 # Default setting. speed = None unpatched = 0 reset = 0 wait = 0 # wait at the end goaddr = None bslobj = bsl.BootStrapLoader() toinit = [] todo = [] startaddr = None size = 2 outputformat = HEX notimeout = 0 bslrepl = None mayuseBSL = 1 forceBSL = 0 sys.stderr.write("MSP430 Bootstrap Loader Version: %s\n" % VERSION) try: opts, args = getopt.getopt( sys.argv[1:], "hc:P:wf:m:eEpvrg:UDudsxbiITNB:S:V14", [ "help", "comport=", "password="******"wait", "framesize=", "erasecycles=", "masserase", "erasecheck", "program", "verify", "reset", "go=", "unpatched", "debug", "upload=", "download=", "size=", "hex", "bin", "ihex", "intelhex", "titext", "notimeout", "bsl=", "speed=", "bslversion", "f1x", "f4x", "invert-reset", "invert-test", "no-BSL-download", "force-BSL-download", "erase=", "slow", "swap-reset-test", "test-on-tx", "ignore-answer" ]) except getopt.GetoptError: # print help information and exit: usage() sys.exit(2) for o, a in opts: if o in ("-h", "--help"): usage() sys.exit() elif o in ("-c", "--comport"): try: comPort = int(a) # try to convert decimal except ValueError: comPort = a # take the string and let serial driver decide elif o in ("-P", "--password"): # extract password from file bslobj.passwd = legacy_memory(memory.load(a)).getMemrange( 0xffe0, 0xffff) elif o in ("-w", "--wait"): wait = 1 elif o in ("-f", "--framesize"): try: maxData = int(a) # try to convert decimal except ValueError: sys.stderr.write("Framesize must be a valid number\n") sys.exit(2) # Make sure that conditions for maxData are met: # ( >= 16 and == n*16 and <= MAX_DATA_BYTES!) if maxData > bsl.BootStrapLoader.MAX_DATA_BYTES: maxData = bsl.BootStrapLoader.MAX_DATA_BYTES elif maxData < 16: maxData = 16 bslobj.maxData = maxData - (maxData % 16) sys.stderr.write( "Max. number of data bytes within one frame set to %i.\n" % maxData) elif o in ("-m", "--erasecycles"): try: meraseCycles = int(a) # try to convert decimal except ValueError: sys.stderr.write("Erasecycles must be a valid number\n") sys.exit(2) # sanity check of value if meraseCycles < 1: sys.stderr.write("Erasecycles must be a positive number\n") sys.exit(2) if meraseCycles > 20: sys.stderr.write( "Warning: erasecycles set to a large number (>20): %d\n" % meraseCycles) sys.stderr.write("Number of mass erase cycles set to %i.\n" % meraseCycles) bslobj.meraseCycles = meraseCycles elif o in ("-e", "--masserase"): toinit.append(bslobj.actionMassErase) # Erase entire Flash elif o in ("-m", "--mainerase"): toinit.append(bslobj.actionMainErase) # Erase main Flash elif o == "--erase": if '-' in a: adr, adr2 = a.split('-', 1) try: adr = int(adr, 0) except ValueError: sys.stderr.write( "Address range start address must be a valid number in dec, hex or octal\n" ) sys.exit(2) try: adr2 = int(adr2, 0) except ValueError: sys.stderr.write( "Address range end address must be a valid number in dec, hex or octal\n" ) sys.exit(2) while adr <= adr2: if adr < 0x1100: modulo = 64 # F2xx:64: F1xx, F4xx: 128 (segments get erased twice) elif adr < 0x1200: modulo = 256 else: modulo = 512 adr = adr - (adr % modulo) toinit.append(bslobj.makeActionSegmentErase(adr)) adr = adr + modulo else: try: seg = int(a, 0) toinit.append(bslobj.makeActionSegmentErase(seg)) except ValueError: sys.stderr.write( "Segment address must be a valid number in dec, hex or octal or a range adr1-adr2\n" ) sys.exit(2) elif o in ("-E", "--erasecheck"): toinit.append(bslobj.actionEraseCheck) # Erase Check (by file) elif o in ("-p", "--programm"): todo.append(bslobj.actionProgram) # Program file elif o in ("-v", "--verify"): todo.append(bslobj.actionVerify) # Verify file elif o in ("-r", "--reset"): reset = 1 elif o in ("-g", "--go"): try: goaddr = int(a) # try to convert decimal except ValueError: try: goaddr = int(a[2:], 16) # try to convert hex except ValueError: sys.stderr.write("Go address must be a valid number\n") sys.exit(2) wait = 1 elif o in ("-U", "--unpatched"): unpatched = 1 elif o in ("-D", "--debug"): DEBUG = DEBUG + 1 bsl.DEBUG = bsl.DEBUG + 1 elif o in ("-u", "--upload"): try: startaddr = int(a) # try to convert decimal except ValueError: try: startaddr = int(a, 16) # try to convert hex except ValueError: sys.stderr.write("Upload address must be a valid number\n") sys.exit(2) elif o in ("-s", "--size"): try: size = int(a) except ValueError: try: size = int(a, 16) except ValueError: sys.stderr.write("Size must be a valid number\n") sys.exit(2) # outut formats elif o in ("-x", "--hex"): outputformat = HEX elif o in ("-b", "--bin"): outputformat = BINARY elif o in ("-i", "--ihex"): outputformat = INTELHEX # input formats elif o in ("-I", "--intelhex"): filetype = 0 elif o in ("-T", "--titext"): filetype = 1 # others elif o in ("-N", "--notimeout"): notimeout = 1 elif o in ("-B", "--bsl"): bslrepl = legacy_memory(memory.load(a)) # File to program elif o in ("-V", "--bslversion"): todo.append(bslobj.actionReadBSLVersion ) # load replacement BSL as first item elif o in ("-S", "--speed"): try: speed = int(a) # try to convert decimal except ValueError: sys.stderr.write("Speed must be decimal number\n") sys.exit(2) elif o in ("-1", "--f1x"): bslobj.cpu = bsl.F1x elif o in ("-4", "--f4x"): bslobj.cpu = bsl.F4x elif o in ("--invert-reset", ): bslobj.invertRST = 1 elif o in ("--invert-test", ): bslobj.invertTEST = 1 elif o in ("--no-BSL-download", ): mayuseBSL = 0 elif o in ("--force-BSL-download", ): forceBSL = 1 elif o in ("--slow", ): bslobj.slowmode = 1 elif o in ("--swap-reset-test", ): bslobj.swapResetTest = 1 elif o in ("--test-on-tx", ): bslobj.testOnTX = 1 elif o in ("--ignore-answer", ): bslobj.ignoreAnswer = 1 if len(args) == 0: sys.stderr.write("Use -h for help\n") elif len(args) == 1: # a filename is given if not todo: # if there are no actions yet todo.extend([ # add some useful actions... bslobj.actionProgram, bslobj.actionVerify, ]) filename = args[0] else: # number of args is wrong usage() sys.exit(2) if DEBUG: # debug infos sys.stderr.write("Debug level set to %d\n" % DEBUG) sys.stderr.write("Python version: %s\n" % sys.version) #sanity check of options if notimeout and goaddr is not None and startaddr is not None: sys.stderr.write( "Option --notimeout can not be used together with both --upload and --go\n" ) sys.exit(1) if notimeout: sys.stderr.write( "Warning: option --notimeout can cause improper function in some cases!\n" ) bslobj.timeout = 0 if goaddr and reset: sys.stderr.write( "Warning: option --reset ignored as --go is specified!\n") reset = 0 if startaddr and reset: sys.stderr.write( "Warning: option --reset ignored as --upload is specified!\n") reset = 0 if toinit: if DEBUG > 0: # debug #show a nice list of sheduled actions sys.stderr.write("TOINIT list:\n") for f in toinit: try: sys.stderr.write(" %s\n" % f.func_name) except AttributeError: sys.stderr.write(" %r\n" % f) if todo: if DEBUG > 0: # debug #show a nice list of sheduled actions sys.stderr.write("TODO list:\n") for f in todo: try: sys.stderr.write(" %s\n" % f.func_name) except AttributeError: sys.stderr.write(" %r\n" % f) sys.stderr.flush() #prepare data to download if filetype is not None: # if the filetype is given... if filename is None: raise ValueError("No filename but filetype specified") if filename == '-': # get data from stdin file = sys.stdin else: file = open(filename, "rb") # or from a file if filetype == 0: # select load function bslobj.data = legacy_memory(memory.load(filename, file, 'ihex')) # intel hex elif filetype == 1: bslobj.data = legacy_memory(memory.load(filename, file, 'titext')) # TI's format else: raise ValueError("Illegal filetype specified") else: # no filetype given... if filename == '-': # for stdin: bslobj.data = legacy_memory( memory.load(filename, sys.stdin, 'ihex')) # assume intel hex elif filename: bslobj.data = legacy_memory( memory.load(filename)) # autodetect otherwise if DEBUG > 3: sys.stderr.write("File: %r" % filename) bslobj.comInit(comPort) # init port #initialization list if toinit: # erase and erase check if DEBUG: sys.stderr.write("Preparing device ...\n") #bslobj.actionStartBSL(usepatch=0, adjsp=0) # no workarounds needed #if speed: bslobj.actionChangeBaudrate(speed) # change baud rate as fast as possible for f in toinit: f() if todo or goaddr or startaddr: if DEBUG: sys.stderr.write("Actions ...\n") #connect to the BSL bslobj.actionStartBSL( usepatch=not unpatched, replacementBSL=bslrepl, forceBSL=forceBSL, mayuseBSL=mayuseBSL, speed=speed, ) #work list if todo: for f in todo: f() # work through todo list if reset: # reset device first if desired bslobj.actionReset() if goaddr is not None: # start user program at specified address bslobj.actionRun(goaddr) # load PC and execute # upload data block and output if startaddr is not None: if goaddr: # if a program was started... # don't restart BSL but wait for the device to enter it itself sys.stderr.write("Waiting for device to reconnect for upload: ") sys.stderr.flush() bslobj.txPasswd(bslobj.passwd, wait=1) # synchronize, try forever... data = bslobj.uploadData(startaddr, size) # upload data else: data = bslobj.uploadData(startaddr, size) # upload data if outputformat == HEX: # depending on output format hexdump((startaddr, data)) # print a hex display elif outputformat == INTELHEX: # output a intel-hex file address = startaddr start = 0 while start < len(data): end = start + 16 if end > len(data): end = len(data) sys.stdout.write(intelhex._ihexline(address, data[start:end])) start += 16 address += 16 sys.stdout.write(intelhex._ihexline( 0, [], end=True)) # append no data but an end line else: sys.stdout.write(data) # binary output w/o newline! wait = 0 # wait makes no sense as after the upload the device is still in BSL if wait: # wait at the end if desired sys.stderr.write("Press <ENTER> ...\n") # display a prompt sys.stderr.flush() input() # wait for newline bslobj.comDone() # Release serial communication port
def inner_main(): from optparse import OptionParser parser = OptionParser(usage="""\ %prog [options] [INPUT...] Simple hex file conversion tool. It is also possible to specify multiple input files and create a single, merged output. """) parser.add_option("-o", "--output", dest="output", help="write result to given file", metavar="DESTINATION") parser.add_option("-i", "--input-format", dest="input_format", help="input format name (%s)" % (', '.join(memory.load_formats), ), default=None, metavar="TYPE") parser.add_option("-f", "--output-format", dest="output_format", help="output format name (%s)" % (', '.join(memory.save_formats), ), default="titext", metavar="TYPE") parser.add_option("-d", "--debug", dest="debug", help="print debug messages", default=False, action='store_true') (options, args) = parser.parse_args() if options.input_format is not None and options.input_format not in memory.load_formats: parser.error('Input format %s not supported.' % (options.input_format)) if options.output_format not in memory.save_formats: parser.error('Output format %s not supported.' % (options.output_format)) if not args: # if no files are given, read from stdin args = ['-'] # default to TI-Text if no format is given if options.input_format is None: options.input_format = 'titext' global debug debug = options.debug # prepare output if options.output is None: try: out = sys.stdout.buffer #detach() except AttributeError: out = sys.stdout else: out = open(options.output, 'wb') # get input data = memory.Memory() # prepare downloaded data for filename in args: if filename == '-': try: fileobj = sys.stdin.detach() except AttributeError: fileobj = sys.stdin data.merge( memory.load('<stdin>', fileobj, format=options.input_format)) else: data.merge(memory.load(filename, format=options.input_format)) # write ihex file memory.save(data, out, options.output_format)
out = sys.stdout if sys.platform == "win32": # ensure that the console is in binary mode import os, msvcrt msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY) else: out = file(options.output, 'wb') # prepare data to download data = memory.Memory() # prepare downloaded data for filename in args: if filename == '-': data.merge( memory.load('<stdin>', sys.stdin, format=options.input_format or "titext")) else: data.merge(memory.load(filename, format=options.input_format)) jtagobj.data = data # prepare downloaded data if options.verbose > 5: sys.stderr.write("File(s): %r\n" % args) # debug messages if toinit: if options.verbose: # debug # show a nice list of scheduled actions sys.stderr.write("TOINIT list:\n") for f in toinit: try:
def inner_main(): from optparse import OptionParser parser = OptionParser(usage="""\ %prog [options] [INPUT...] Simple hex file conversion tool. It is also possible to specify multiple input files and create a single, merged output. """) parser.add_option("-o", "--output", dest="output", help="write result to given file", metavar="DESTINATION") parser.add_option("-i", "--input-format", dest="input_format", help="input format name (%s)" % (', '.join(memory.load_formats),), default=None, metavar="TYPE") parser.add_option("-f", "--output-format", dest="output_format", help="output format name (%s)" % (', '.join(memory.save_formats),), default="titext", metavar="TYPE") parser.add_option("-d", "--debug", dest="debug", help="print debug messages", default=False, action='store_true') (options, args) = parser.parse_args() if options.input_format is not None and options.input_format not in memory.load_formats: parser.error('Input format %s not supported.' % (options.input_format)) if options.output_format not in memory.save_formats: parser.error('Output format %s not supported.' % (options.output_format)) if not args: # if no files are given, read from stdin args = ['-'] # default to TI-Text if no format is given if options.input_format is None: options.input_format = 'titext' global debug debug = options.debug # prepare output if options.output is None: try: out = sys.stdout.buffer #detach() except AttributeError: out = sys.stdout else: out = open(options.output, 'wb') # get input data = memory.Memory() # prepare downloaded data for filename in args: if filename == '-': try: fileobj = sys.stdin.detach() except AttributeError: fileobj = sys.stdin data.merge(memory.load('<stdin>', fileobj, format=options.input_format)) else: data.merge(memory.load(filename, format=options.input_format)) # write ihex file memory.save(data, out, options.output_format)
# prepare output if options.output is None: out = sys.stdout if sys.platform == "win32": # ensure that the console is in binary mode import os, msvcrt msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY) else: out = file(options.output, 'wb') # prepare data to download data = memory.Memory() # prepare downloaded data for filename in args: if filename == '-': data.merge(memory.load('<stdin>', sys.stdin, format=options.input_format or "titext")) else: data.merge(memory.load(filename, format=options.input_format)) jtagobj.data = data # prepare downloaded data if options.verbose > 5: sys.stderr.write("File(s): %r\n" % args) # debug messages if toinit: if options.verbose: # debug # show a nice list of scheduled actions sys.stderr.write("TOINIT list:\n") for f in toinit: try: sys.stderr.write(" %s\n" % f.func_name)
def parse_args(self): (self.options, self.args) = None, [] # parse_args may terminate... (self.options, self.args) = self.parser.parse_args() self.debug = self.options.debug self.verbose = self.options.verbose if self.verbose > 3: level = logging.DEBUG elif self.verbose > 2: level = logging.INFO else: level = logging.WARN logging.basicConfig(level=level) if self.verbose > 1: # debug infos sys.stderr.write("Debug is %s\n" % self.options.debug) sys.stderr.write("Verbosity level set to %d\n" % self.options.verbose) #~ sys.stderr.write("logging module level set to %s\n" % (level,)) sys.stderr.write("Python version: %s\n" % sys.version) if self.options.input_format is not None and self.options.input_format not in memory.load_formats: self.parser.error('Input format %s not supported.' % (self.options.input_format)) if self.options.output_format not in memory.save_formats: self.parser.error('Output format %s not supported.' % (self.options.output_format)) # sanity check of options if self.options.do_run is not None and self.options.do_reset: if self.verbose: sys.stderr.write( "Warning: option --reset ignored as --go is specified!\n") self.options.do_reset = False if self.options.upload_list and self.options.do_reset: if self.verbose: sys.stderr.write( "Warning: option --reset ignored as --upload is specified!\n" ) self.options.do_reset = False if self.options.upload_list and self.options.do_wait: if self.verbose: sys.stderr.write( "Warning: option --wait ignored as --upload is specified!\n" ) self.options.do_wait = False # create a list of functions an arguments if self.options.do_mass_erase: self.add_action(self.mass_erase) if self.options.do_main_erase: self.add_action(self.main_erase) if self.options.do_erase_by_file: self.add_action(self.erase_by_file) if self.options.do_info_erase: self.add_action(self.erase_infomem) for a in self.options.erase_list: try: adr, adr2 = parseAddressRange(a) if adr2 is not None: while adr <= adr2: if not (0x1000 <= adr <= 0xffff): self.parser.error( "Start address for --erase is not within Flash memory: 0x%04x" % (adr, )) elif adr < 0x1100: modulo = 64 # F2xx XXX: on F1xx/F4xx are segments erased twice elif adr < 0x1200: modulo = 256 else: modulo = 512 adr = adr - (adr % modulo) self.add_action(self.erase, adr) adr = adr + modulo else: self.add_action(self.erase, adr) except ValueError as e: self.parser.error("--erase: %s" % e) default_action = True if self.options.do_erase_check: self.add_action(self.erase_check_by_file) default_action = False if self.options.do_program: self.add_action(self.program_file) default_action = False if self.options.do_verify: self.add_action(self.verify_by_file) default_action = False if self.options.do_upload_by_file: self.add_action(self.upload_by_file) default_action = False # as default action (no other given by user), program if a file is given if default_action and self.args: self.add_action(self.program_file) for a in self.options.upload_list: try: start, end = parseAddressRange(a) if end is None: end = start + 15 self.add_action(self.upload, start, end) except ValueError as e: self.parser.error("--upload: %s" % e) if self.options.do_reset: self.add_action(self.reset) if self.options.upload_list or self.options.do_upload_by_file: self.upload_data = memory.Memory() if self.options.do_run: self.add_action(self.execute, self.options.do_run) else: # XXX reset otherwise, independently of -r option. imitate old behavior self.add_action(self.reset) # prepare output if self.options.output is None: self.output = sys.stdout if sys.platform == "win32": # ensure that the console is in binary mode import os, msvcrt #msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY) else: self.output = open(self.options.output, 'wb') # prepare data to download / load files self.download_data = memory.Memory() # prepare downloaded data for filename in self.args: if filename == '-': data = memory.load('<stdin>', sys.stdin, format=self.options.input_format or "titext") else: data = memory.load(filename, format=self.options.input_format) self.download_data.merge(data)
def main(): global DEBUG import getopt filetype = None filename = None comPort = 0 # Default setting. speed = None unpatched = 0 reset = 0 wait = 0 # wait at the end goaddr = None bslobj = bsl.BootStrapLoader() toinit = [] todo = [] startaddr = None size = 2 outputformat= HEX notimeout = 0 bslrepl = None mayuseBSL = 1 forceBSL = 0 sys.stderr.write("MSP430 Bootstrap Loader Version: %s\n" % VERSION) try: opts, args = getopt.getopt(sys.argv[1:], "hc:P:wf:m:eEpvrg:UDudsxbiITNB:S:V14", ["help", "comport=", "password="******"wait", "framesize=", "erasecycles=", "masserase", "erasecheck", "program", "verify", "reset", "go=", "unpatched", "debug", "upload=", "download=", "size=", "hex", "bin", "ihex", "intelhex", "titext", "notimeout", "bsl=", "speed=", "bslversion", "f1x", "f4x", "invert-reset", "invert-test", "no-BSL-download", "force-BSL-download", "erase=", "slow", "swap-reset-test", "test-on-tx", "ignore-answer"] ) except getopt.GetoptError: # print help information and exit: usage() sys.exit(2) for o, a in opts: if o in ("-h", "--help"): usage() sys.exit() elif o in ("-c", "--comport"): try: comPort = int(a) # try to convert decimal except ValueError: comPort = a # take the string and let serial driver decide elif o in ("-P", "--password"): # extract password from file bslobj.passwd = legacy_memory(memory.load(a)).getMemrange(0xffe0, 0xffff) elif o in ("-w", "--wait"): wait = 1 elif o in ("-f", "--framesize"): try: maxData = int(a) # try to convert decimal except ValueError: sys.stderr.write("Framesize must be a valid number\n") sys.exit(2) # Make sure that conditions for maxData are met: # ( >= 16 and == n*16 and <= MAX_DATA_BYTES!) if maxData > bsl.BootStrapLoader.MAX_DATA_BYTES: maxData = bsl.BootStrapLoader.MAX_DATA_BYTES elif maxData < 16: maxData = 16 bslobj.maxData = maxData - (maxData % 16) sys.stderr.write( "Max. number of data bytes within one frame set to %i.\n" % maxData) elif o in ("-m", "--erasecycles"): try: meraseCycles = int(a) # try to convert decimal except ValueError: sys.stderr.write("Erasecycles must be a valid number\n") sys.exit(2) # sanity check of value if meraseCycles < 1: sys.stderr.write("Erasecycles must be a positive number\n") sys.exit(2) if meraseCycles > 20: sys.stderr.write("Warning: erasecycles set to a large number (>20): %d\n" % meraseCycles) sys.stderr.write( "Number of mass erase cycles set to %i.\n" % meraseCycles) bslobj.meraseCycles = meraseCycles elif o in ("-e", "--masserase"): toinit.append(bslobj.actionMassErase) # Erase entire Flash elif o in ("-m", "--mainerase"): toinit.append(bslobj.actionMainErase) # Erase main Flash elif o == "--erase": if '-' in a: adr, adr2 = a.split('-', 1) try: adr = int(adr, 0) except ValueError: sys.stderr.write("Address range start address must be a valid number in dec, hex or octal\n") sys.exit(2) try: adr2 = int(adr2, 0) except ValueError: sys.stderr.write("Address range end address must be a valid number in dec, hex or octal\n") sys.exit(2) while adr <= adr2: if adr < 0x1100: modulo = 64 # F2xx:64: F1xx, F4xx: 128 (segments get erased twice) elif adr < 0x1200: modulo = 256 else: modulo = 512 adr = adr - (adr % modulo) toinit.append(bslobj.makeActionSegmentErase(adr)) adr = adr + modulo else: try: seg = int(a, 0) toinit.append(bslobj.makeActionSegmentErase(seg)) except ValueError: sys.stderr.write("Segment address must be a valid number in dec, hex or octal or a range adr1-adr2\n") sys.exit(2) elif o in ("-E", "--erasecheck"): toinit.append(bslobj.actionEraseCheck) # Erase Check (by file) elif o in ("-p", "--programm"): todo.append(bslobj.actionProgram) # Program file elif o in ("-v", "--verify"): todo.append(bslobj.actionVerify) # Verify file elif o in ("-r", "--reset"): reset = 1 elif o in ("-g", "--go"): try: goaddr = int(a) # try to convert decimal except ValueError: try: goaddr = int(a[2:],16) # try to convert hex except ValueError: sys.stderr.write("Go address must be a valid number\n") sys.exit(2) wait = 1 elif o in ("-U", "--unpatched"): unpatched = 1 elif o in ("-D", "--debug"): DEBUG = DEBUG + 1 bsl.DEBUG = bsl.DEBUG + 1 elif o in ("-u", "--upload"): try: startaddr = int(a) # try to convert decimal except ValueError: try: startaddr = int(a,16) # try to convert hex except ValueError: sys.stderr.write("Upload address must be a valid number\n") sys.exit(2) elif o in ("-s", "--size"): try: size = int(a) except ValueError: try: size = int(a,16) except ValueError: sys.stderr.write("Size must be a valid number\n") sys.exit(2) # outut formats elif o in ("-x", "--hex"): outputformat = HEX elif o in ("-b", "--bin"): outputformat = BINARY elif o in ("-i", "--ihex"): outputformat = INTELHEX # input formats elif o in ("-I", "--intelhex"): filetype = 0 elif o in ("-T", "--titext"): filetype = 1 # others elif o in ("-N", "--notimeout"): notimeout = 1 elif o in ("-B", "--bsl"): bslrepl = legacy_memory(memory.load(a)) # File to program elif o in ("-V", "--bslversion"): todo.append(bslobj.actionReadBSLVersion) # load replacement BSL as first item elif o in ("-S", "--speed"): try: speed = int(a) # try to convert decimal except ValueError: sys.stderr.write("Speed must be decimal number\n") sys.exit(2) elif o in ("-1", "--f1x"): bslobj.cpu = bsl.F1x elif o in ("-4", "--f4x"): bslobj.cpu = bsl.F4x elif o in ("--invert-reset", ): bslobj.invertRST = 1 elif o in ("--invert-test", ): bslobj.invertTEST = 1 elif o in ("--no-BSL-download", ): mayuseBSL = 0 elif o in ("--force-BSL-download", ): forceBSL = 1 elif o in ("--slow", ): bslobj.slowmode = 1 elif o in ("--swap-reset-test", ): bslobj.swapResetTest = 1 elif o in ("--test-on-tx", ): bslobj.testOnTX = 1 elif o in ("--ignore-answer", ): bslobj.ignoreAnswer = 1 if len(args) == 0: sys.stderr.write("Use -h for help\n") elif len(args) == 1: # a filename is given if not todo: # if there are no actions yet todo.extend([ # add some useful actions... bslobj.actionProgram, bslobj.actionVerify, ]) filename = args[0] else: # number of args is wrong usage() sys.exit(2) if DEBUG: #debug infos sys.stderr.write("Debug level set to %d\n" % DEBUG) sys.stderr.write("Python version: %s\n" % sys.version) #sanity check of options if notimeout and goaddr is not None and startaddr is not None: sys.stderr.write("Option --notimeout can not be used together with both --upload and --go\n") sys.exit(1) if notimeout: sys.stderr.write("Warning: option --notimeout can cause improper function in some cases!\n") bslobj.timeout = 0 if goaddr and reset: sys.stderr.write("Warning: option --reset ignored as --go is specified!\n") reset = 0 if startaddr and reset: sys.stderr.write("Warning: option --reset ignored as --upload is specified!\n") reset = 0 if toinit: if DEBUG > 0: #debug #show a nice list of sheduled actions sys.stderr.write("TOINIT list:\n") for f in toinit: try: sys.stderr.write(" %s\n" % f.func_name) except AttributeError: sys.stderr.write(" %r\n" % f) if todo: if DEBUG > 0: #debug #show a nice list of sheduled actions sys.stderr.write("TODO list:\n") for f in todo: try: sys.stderr.write(" %s\n" % f.func_name) except AttributeError: sys.stderr.write(" %r\n" % f) sys.stderr.flush() #prepare data to download if filetype is not None: # if the filetype is given... if filename is None: raise ValueError("No filename but filetype specified") if filename == '-': # get data from stdin file = sys.stdin else: file = open(filename, "rb") # or from a file if filetype == 0: # select load function bslobj.data = legacy_memory(memory.load(filename, file, 'ihex')) # intel hex elif filetype == 1: bslobj.data = legacy_memory(memory.load(filename, file, 'titext')) # TI's format else: raise ValueError("Illegal filetype specified") else: # no filetype given... if filename == '-': # for stdin: bslobj.data = legacy_memory(memory.load(filename, sys.stdin, 'ihex')) # assume intel hex elif filename: bslobj.data = legacy_memory(memory.load(filename)) # autodetect otherwise if DEBUG > 3: sys.stderr.write("File: %r" % filename) bslobj.comInit(comPort) # init port #initialization list if toinit: #erase and erase check if DEBUG: sys.stderr.write("Preparing device ...\n") #bslobj.actionStartBSL(usepatch=0, adjsp=0) # no workarounds needed #if speed: bslobj.actionChangeBaudrate(speed) # change baud rate as fast as possible for f in toinit: f() if todo or goaddr or startaddr: if DEBUG: sys.stderr.write("Actions ...\n") #connect to the BSL bslobj.actionStartBSL( usepatch=not unpatched, replacementBSL=bslrepl, forceBSL=forceBSL, mayuseBSL=mayuseBSL, speed=speed, ) #work list if todo: for f in todo: f() # work through todo list if reset: # reset device first if desired bslobj.actionReset() if goaddr is not None: # start user program at specified address bslobj.actionRun(goaddr) # load PC and execute # upload data block and output if startaddr is not None: if goaddr: # if a program was started... # don't restart BSL but wait for the device to enter it itself sys.stderr.write("Waiting for device to reconnect for upload: ") sys.stderr.flush() bslobj.txPasswd(bslobj.passwd, wait=1) # synchronize, try forever... data = bslobj.uploadData(startaddr, size) # upload data else: data = bslobj.uploadData(startaddr, size) # upload data if outputformat == HEX: # depending on output format hexdump( (startaddr, data) ) # print a hex display elif outputformat == INTELHEX: # output a intel-hex file address = startaddr start = 0 while start < len(data): end = start + 16 if end > len(data): end = len(data) sys.stdout.write(intelhex._ihexline(address, data[start:end])) start += 16 address += 16 sys.stdout.write(intelhex._ihexline(0, [], end=True)) # append no data but an end line else: sys.stdout.write(data) # binary output w/o newline! wait = 0 # wait makes no sense as after the upload the device is still in BSL if wait: # wait at the end if desired sys.stderr.write("Press <ENTER> ...\n") # display a prompt sys.stderr.flush() raw_input() # wait for newline bslobj.comDone() # Release serial communication port
def main(): from optparse import OptionParser, OptionGroup, TitledHelpFormatter # i dont like how texts are re-wrapped and paragraphs are joined. get rid # of that class Formatter(TitledHelpFormatter): def format_description(self, description): return description parser = OptionParser( usage="""\ %prog [OPTIONS] [FILE [FILE...]] Version: %version If "-" is specified as file the data is read from stdin and TI-text format is expected by default. """, formatter=Formatter(), version=VERSION) vars = { 'prog': sys.argv[0], 'version': VERSION, 'msp430': (sys.platform != 'win32') and 'libMSP430.so' or 'MSP430.dll', 'msp430mspgcc': (sys.platform != 'win32') and 'libMSP430mspgcc.so' or 'MSP430mspgcc.dll', } parser.add_option( "--help-backend", dest="help_backend", help="show help about the different backends", default=False, action='store_true') parser.add_option( "-d", "--debug", dest="debug", help="print debug messages", default=False, action='store_true') parser.add_option( "-v", "--verbose", dest="verbose", help="show more messages (can be given multiple times)", default=0, action='count') parser.add_option( "-q", "--quiet", dest="quiet", help="suppress all messages", default=False, action='store_true') parser.add_option( "-R", "--ramsize", dest="ramsize", type="int", help="specify the amount of RAM to be used to program flash (default: auto detected)", default=None) group = OptionGroup(parser, "Programing", """\ File format is auto detected, unless --input-format is used. Preferred file extensions are ".txt" for TI-Text format, ".a43" or ".hex" for Intel HEX. ELF files can also be loaded. """) group.add_option( "-i", "--input-format", dest="input_format", help="input format name (%s)" % (', '.join(memory.load_formats),), default=None, metavar="TYPE") group.add_option( "-S", "--progress", dest="progress", help="show progress while programming", default=False, action='store_true') parser.add_option_group(group) group = OptionGroup(parser, "Connection", """\ Note: On Windows, use "USB", "TIUSB" or "COM5" etc if using MSP430.dll from TI. On other platforms, e.g. Linux, use "/dev/ttyUSB0" etc. if using libMSP430.so. If a %(msp430)s is found, it is preferred, otherwise %(msp430mspgcc)s is used. Note: --slowdown > 50 can result in failures for the RAM size auto detection (use --ramsize option to fix this). Use the --verbose option and watch the outputs. The DCO clock adjustment and thus the Flash timing may be inaccurate for large values. """ % vars) group.add_option( "--backend", dest="backend", help="select an alternate backend. See --help-backend for more information", default=None) group.add_option( "-l", "--lpt", dest="port_name", metavar="PORT", help='specify an other parallel port or serial port for the USBFET (the later ' 'requires %(msp430)s instead of %(msp430mspgcc)s). (defaults to "LPT1" ' '("/dev/parport0" on Linux))' % vars, default=None) group.add_option( "--spy-bi-wire-jtag", dest="spy_bi_wire_jtag", help="interface is 4 wire on a spy-bi-wire capable device", default=False, action='store_true') group.add_option( "--spy-bi-wire", dest="spy_bi_wire", help="interface is 2 wire on a spy-bi-wire capable device", default=False, action='store_true') group.add_option( "--slowdown", dest="slowdown", metavar="MICROSECONDS", help="artificially slow down the communication. Can help with long " "lines, try values between 1 and 50 (parallel port interface with " "mspgcc's HIL library only). (experts only)", default=None) parser.add_option_group(group) group = OptionGroup(parser, "Funclets", """\ Note: Writing and/or reading RAM before and/or after running a funclet may not work as expected on devices with the JTAG bug like the F123. Note: Only possible with %(msp430mspgcc)s, not other backends. """ % vars) group.add_option( "--funclet", dest="funclet", help="the given file is a funclet (a small program to be run in RAM)", default=None, metavar="FILENAME") group.add_option( "--parameter", dest="funclet_parameter", metavar="<KEY>=<VALUE>", help='Pass parameters to funclets. Registers can be written like ' '"R15=123" or "R4=0x55" A string can be written to memory with ' '"0x2e0=hello" --parameter can be given more than once', default=[], action='append') group.add_option( "--result", dest="funclet_result", metavar="VALUE", help='Read results from funclets. "Rall" reads all registers (case ' 'insensitive) "R15" reads R15 etc. Address ranges can be read ' 'with "0x2e0-0x2ff". See also --upload. --result can be given ' 'more than once.', default=[], action='append') group.add_option( "--timeout", dest="funclet_timeout", metavar="VALUE", type="float", help='Abort the funclet after the given time in seconds if it does ' 'not exit no itself. (default 1)', default=1) parser.add_option_group(group) group = OptionGroup(parser, "Program flow specifiers", """\ Program flow specifiers default to "-P" if a file is given. Don't forget to specify "-e", "-eE" or "-m" when programming flash! "-P" already verifies the programmed data, "-V" adds an additional verification through uploading the written data for a 1:1 compare. No default action is taken if "-P" and/or "-V" is given, say specifying only "-V" does a "check by file" of a programmed device. Multiple --erase options are allowed. It is possible to use address ranges such as 0xf000-0xf0ff or 0xf000/4k. NOTE: SegmentA on F2xx is NOT erased with --masserase, that must be done separately with --erase=0x10c0 or --eraseinfo". """) group.add_option( "-e", "--masserase", dest="do_mass_erase", help="mass erase (clear all flash memory)", default=False, action='store_true') group.add_option( "-m", "--mainerase", dest="do_main_erase", help="erase main flash memory only", default=False, action='store_true') group.add_option( "--eraseinfo", dest="do_info_erase", help="erase info flash memory only (0x1000-0x10ff)", default=False, action='store_true') group.add_option( "--erase", dest="erase_list", help="selectively erase segment at the specified address or address range", default=[], action='append') group.add_option( "-E", "--erasecheck", dest="do_erase_check", help="erase check by file", default=False, action='store_true') group.add_option( "-P", "--program", dest="do_program", help="program file", default=False, action='store_true') group.add_option( "-V", "--verify", dest="do_verify", help="verify by file", default=False, action='store_true') parser.add_option_group(group) group = OptionGroup(parser, "JTAG fuse", """\ WARNING: This is not reversible, use with care! Note: Not supported with the simple parallel port adapter (7V source required).", """) group.add_option( "--secure", dest="do_secure", help="blow JTAG security fuse", default=False, action='store_true') parser.add_option_group(group) group = OptionGroup(parser, "Data retrieving", """\ It is possible to use address ranges such as 0xf000-0xf0ff or 0xf000/256. Multiple --upload options are allowed. """) group.add_option( "-u", "--upload", dest="upload_list", metavar="ADDRESS", help='upload a data block, can be passed multiple times', default=[], action='append') group.add_option( "-o", "--output", dest="output", help="write result to given file", metavar="DESTINATION") group.add_option( "-f", "--output-format", dest="output_format", help="output format name (%s)" % (', '.join(memory.save_formats),), default="hex", metavar="TYPE") parser.add_option_group(group) group = OptionGroup(parser, "Do before exit") group.add_option( "-g", "--go", dest="do_run", metavar="ADDRESS", type="int", help='start program execution at specified address, this implies option --wait', default=None, action='store') group.add_option( "-r", "--reset", dest="do_reset", help="perform a normal device reset that will start the program that is specified in the reset interrupt vector", default=False, action='store_true') group.add_option( "-w", "--wait", dest="wait", help="wait for <ENTER> before closing the port", default=False, action='store_true') group.add_option( "--no-close", dest="no_close", help="do not close port on exit, allows to power devices from the parallel port interface", default=False, action='store_true') parser.add_option_group(group) group = OptionGroup(parser, "Examples", """\ Mass erase and program from file: "%(prog)s -e firmware.elf" Dump information memory: "%(prog)s --upload=0x1000-0x10ff" """ % vars) parser.add_option_group(group) (options, args) = parser.parse_args() if options.input_format is not None and options.input_format not in memory.load_formats: parser.error('Input format %s not supported.' % (options.input_format)) if options.output_format not in memory.save_formats: parser.error('Output format %s not supported.' % (options.output_format)) reset = False goaddr = None jtagobj = jtag.JTAG() toinit = [] todo = [] uploadlist = [] funclet = None parameters = [] results = [] if options.help_backend: help_on_backends() sys.exit() if options.backend is not None: if options.backend == 'mspgcc': backend = jtag.CTYPES_MSPGCC elif options.backend == 'parjtag': backend = jtag.PARJTAG elif options.backend == 'ti': backend = jtag.CTYPES_TI else: raise parser.error("no such backend: %r" % options.backend) jtag.init_backend(backend) if options.spy_bi_wire: jtag.interface = 'spy-bi-wire' if options.spy_bi_wire_jtag: jtag.interface = 'spy-bi-wire-jtag' if options.do_mass_erase: toinit.append(jtagobj.actionMassErase) # Erase Flash if options.do_main_erase: toinit.append(jtagobj.actionMainErase) # Erase main Flash for a in options.erase_list: try: adr, adr2 = parseAddressRange(a) if adr2 is not None: while adr <= adr2: if not (0x1000 <= adr <= 0xffff): sys.stderr.write("Start address is not within Flash memory\n") sys.exit(2) elif adr < 0x1100: modulo = 64 # F2xx XXX: on F1xx/F4xx are segments erased twice elif adr < 0x1200: modulo = 256 else: modulo = 512 adr = adr - (adr % modulo) toinit.append(jtagobj.makeActionSegmentErase(adr)) adr = adr + modulo else: toinit.append(jtagobj.makeActionSegmentErase(adr)) except ValueError as e: parser.error("--erase: %s" % e) if options.do_info_erase: # F2xx XXX: on F1xx/F4xx are segments erased twice toinit.append(jtagobj.makeActionSegmentErase(0x1000)) toinit.append(jtagobj.makeActionSegmentErase(0x1040)) toinit.append(jtagobj.makeActionSegmentErase(0x1080)) toinit.append(jtagobj.makeActionSegmentErase(0x10c0)) if options.do_erase_check: toinit.append(jtagobj.actionEraseCheck) # Erase Check (by file) if options.do_program: todo.append(jtagobj.actionProgram) # Program file if options.do_verify: todo.append(jtagobj.actionVerify) # Verify file if options.do_secure: todo.append(jtagobj.actionSecure) if options.do_reset: reset = True if options.debug: global DEBUG DEBUG = True if options.verbose: try: jtagobj.setDebugLevel(options.verbose) except IOError: sys.stderr.write("WARNING: Failed to set debug level in backend library\n") memory.DEBUG = options.verbose jtag.DEBUG = options.verbose for a in options.upload_list: try: start, end = parseAddressRange(a) if end is not None: uploadlist.append((start, end)) else: uploadlist.append((start, start + 15)) except ValueError as e: parser.error("--upload: %s" % e) # others if options.funclet: funclet = True if options.progress: jtagobj.showprogess = 1 for a in options.funclet_parameter: if '=' in a: key, value = a.lower().split('=', 2) if key[0] == 'r': regnum = int(key[1:]) value = int(value, 0) parameters.append((jtagobj.setCPURegister, (regnum, value))) else: address = int(key, 0) parameters.append((jtagobj.downloadData, (address, value))) else: parser.erro("Expected <key>=<value> pair in --parameter option, but no '=' found.") for a in options.funclet_result: a = a.lower() if a == 'rall': for regnum in range(16): results.append(('R%-2d = 0x%%04x' % regnum, jtagobj.getCPURegister, (regnum,))) elif a[0] == 'r': regnum = int(a[1:]) results.append(('R%-2d = 0x%%04x' % regnum, jtagobj.getCPURegister, (regnum,))) else: try: start, end = parseAddressRange(a) if end is None: end = start except ValueError as e: parser.error("--result: %s" % e) results.append(('0x%04x: %%r' % start, jtagobj.uploadData, (start, end - start))) if options.quiet: jtagobj.verbose = 0 if options.slowdown is not None: import ctypes if sys.platform == 'win32': HIL_SetSlowdown = ctypes.windll.HIL.HIL_SetSlowdown else: # XXX and posix platforms?! HIL_SetSlowdown = ctypes.cdll.HIL.HIL_SetSlowdown HIL_SetSlowdown = ctypes.windll.HIL.HIL_SetSlowdown HIL_SetSlowdown.argtypes = [ctypes.c_ulong] #~ HIL_SetSlowdown.restype = ctypes.c_int # actually void # set slowdown HIL_SetSlowdown(options.slowdown) if options.verbose: if options.quiet: options.quiet = False sys.stderr.write("Disabling --quiet as --verbose is active\n") if not options.quiet: sys.stderr.write("MSP430 JTAG programmer Version: %s\n" % VERSION) if not args: if not options.quiet: sys.stderr.write("Use -h for help\n") elif args: # a filename is given if not funclet: if not todo: # if there are no actions yet todo.insert(0, jtagobj.actionProgram) # add some useful actions... else: # number of args is wrong parser.error("Unsuitable number of arguments") if options.verbose: # debug infos sys.stderr.write("Debug is %s\n" % DEBUG) sys.stderr.write("Verbosity level set to %d\n" % options.verbose) sys.stderr.write("Python version: %s\n" % sys.version) #~ sys.stderr.write("JTAG backend: %s\n" % jtag.backend) # sanity check of options if goaddr and reset: if not options.quiet: sys.stderr.write("Warning: option --reset ignored as --go is specified!\n") reset = False if options.upload_list and reset: if not options.quiet: sys.stderr.write("Warning: option --reset ignored as --upload is specified!\n") reset = False if options.upload_list and options.wait: if not options.quiet: sys.stderr.write("Warning: option --wait ignored as --upload is specified!\n") options.wait = False # prepare output if options.output is None: out = sys.stdout if sys.platform == "win32": # ensure that the console is in binary mode import os, msvcrt msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY) else: out = open(options.output, 'wb') # prepare data to download data = memory.Memory() # prepare downloaded data for filename in args: if filename == '-': data.merge(memory.load('<stdin>', sys.stdin, format=options.input_format or "titext")) else: data.merge(memory.load(filename, format=options.input_format)) jtagobj.data = data # prepare downloaded data if options.verbose > 5: sys.stderr.write("File(s): %r\n" % args) # debug messages if toinit: if options.verbose: # debug # show a nice list of scheduled actions sys.stderr.write("TOINIT list:\n") for f in toinit: try: sys.stderr.write(" %s\n" % f.func_name) except AttributeError: sys.stderr.write(" %r\n" % f) if todo: if options.verbose: # debug # show a nice list of scheduled actions sys.stderr.write("TODO list:\n") for f in todo: try: sys.stderr.write(" %s\n" % f.func_name) except AttributeError: sys.stderr.write(" %r\n" % f) sys.stderr.flush() abort_due_to_error = 1 release_done = 0 jtagobj.open(options.port_name) # try to open port try: if options.ramsize is not None: jtagobj.setRamsize(options.ramsize) jtagobj.connect() # connect to target # initialization list if toinit: # erase and erase check if options.verbose: sys.stderr.write("Preparing device ...\n") for f in toinit: f() # work list if todo: for f in todo: f() # work through TODO list if reset: # reset device first if desired jtagobj.reset() for function, args in parameters: function(*args) if funclet is not None: # download and start funclet jtagobj.actionFunclet(options.timeout) if goaddr is not None: # start user program at specified address jtagobj.actionRun(goaddr) # load PC and execute for format, function, args in results: print(format % function(*args)) # upload data block and output if uploadlist: if goaddr: # if a program was started... raise NotImplementedError # TODO: # sys.stderr.write("Waiting to device for reconnect for upload: ") data = memory.Memory() for start, end in uploadlist: size = end - start + 1 if options.verbose > 2: sys.stderr.write("Upload 0x%04x %d bytes\n" % (start, size)) data.append(memory.Segment(start, jtagobj.uploadData(start, size))) # upload data memory.save(data, out, options.output_format) options.wait = False # wait makes no sense as after upload, the device is still stopped if options.wait: # wait at the end if desired jtagobj.reset(1, 1) # reset and release target release_done = 1 if not options.quiet: sys.stderr.write("Press <ENTER> ...\n") # display a prompt sys.stderr.flush() input() # wait for newline abort_due_to_error = 0 finally: if abort_due_to_error: sys.stderr.write("Cleaning up after error...\n") if not release_done: jtagobj.reset(1, 1) # reset and release target if not options.no_close: jtagobj.close() # release communication port elif options.verbose: sys.stderr.write("WARNING: JTAG port is left open (--no-close)\n")