import sys import time import traceback from typing import * from .protocol import * FEATURES_OF_MODE = { 1: ["UART", "CMSIS-DAP", "SPI", "I2C", "temperature sensor", "1-wire"], 3: ["JTAG", "SWD"], 4: ["SUMP"] } def get_device_info(dev: DPDevice) -> int: print("%s: protocol version: %02x.%02x, currently in mode %d (%s)" % \ (dev.infotext, dev.protocol_version >> 8, dev.protocol_version & 0xff, dev.current_mode, dev.mode_info[dev.current_mode].infotext) ) print("available modes: %s" % ', '.join(str(x) for x in dev.mode_info.keys())) #for mi, mv in dev.mode_info.items(): # print("\t% 2d: '%s' version %02x.%02x with %sfeatures %s" % \ # (mi, mv.infotext, mv.version >> 8, mv.version & 0xff, # ("no " if len(mv.features) == 0 else ""), # ', '.join(str(x) for x in mv.features)) # TODO: better features display? # ) return 0 def get_mode_info(dev: DPDevice, mode: Optional[str]) -> int: def try_parse(s: str): try: return int(s) except ValueError: return None def is_int(s: str): try: int(s) return True except ValueError: return None if mode is None: mode = dev.current_mode if mode == "all" or (is_int(mode) and int(mode) < 0): for mi, mv in dev.mode_info.items(): featlist = FEATURES_OF_MODE.get(mi, "01234567") print("mode % 2d: %s: version %02x.%02x with %sfeatures %s" % \ (mi, mv.infotext, mv.version >> 8, mv.version & 0xff, ("no " if len(mv.features) == 0 else ""), ', '.join(featlist[x] for x in mv.features)) # TODO: better features display? ) elif is_int(mode): mode = int(mode) featlist = FEATURES_OF_MODE.get(mode, "01234567") if mode in dev.mode_info: mv = dev.mode_info[mode] print("mode %d: %s: version %02x.%02x with %sfeatures %s" % \ (mode, mv.infotext, mv.version >> 8, mv.version & 0xff, ("no " if len(mv.features) == 0 else ""), ', '.join(featlist[x] for x in list(mv.features))) # TODO: better features display? ) return 0 else: print("No mode %d available" % mode) return 1 else: print("Invalid mode '%s'" % mode) return 1 def set_mode(dev: DPDevice, mode: int) -> int: try: dev.set_mode(mode) return 0 except Exception as e: print(str(e)) return 1 # --- def storage_info(dev: DPDevice) -> int: try: res = dev.storage_info() print(repr(res)) # TODO return 0 except Exception as e: print("Could not get storage info: %s" % str(e)) return 1 def storage_flush(dev: DPDevice) -> int: try: dev.storage_flush() return 0 except Exception as e: print("Could not flush persistent storage: %s" % str(e)) return 1 def storage_get(dev: DPDevice, mode: int) -> int: try: res = dev.storage_get(mode) print(repr(res)) # TODO return 0 except Exception as e: print("Could not get storage data of mode %d: %s" % (mode, str(e))) return 1 # --- def uart_hw_flowctl_get(dev: DPDevice) -> int: try: res = dev.m1_usb_hw_flowctl_get() print("Flow control %sabled" % ("en" if res else "dis")) return 0 except Exception as e: print("Could not get flow control state: %s" % str(e)) return 1 def uart_hw_flowctl_set(dev: DPDevice, v: bool) -> int: try: dev.m1_usb_hw_flowctl_set(v) return 0 except Exception as e: print("Could not set flow control state: %s" % str(e)) return 1 # --- def tempsensor_get(dev: DPDevice) -> int: try: res = dev.m1_tempsensor_i2cemul_get() if res is None: print("Temperature sensor I2C emulation disabled") else: print("Temperature sensor I2C device at address 0x%02x" % res) return 0 except Exception as e: print("Could not get temperature sensor I2C emulation: %s" % str(e)) return 1 def tempsensor_set(dev: DPDevice, v: int) -> int: try: old, new = dev.m1_tempsensor_i2cemul_set(v) olds = "disabled" if old is None else ("0x%02x" % old) news = "disabled" if new is None else ("0x%02x" % new) print("Temperature sensor I2C device changed from %s to %s" % (olds, news)) return 0 except Exception as e: print("Could not set temperature sensor I2C emulation: %s" % str(e)) return 1 # --- def jtag_scan(dev: DPDevice, typ: str, start_pin: int, end_pin: int) -> int: SCAN_IDLE = 0x7f SCAN_DONE_F = 0x80 types = { 0x00: 'jtag', 0x01: 'swd', 0x02: 'sbw' } typei = { 'jtag': 0x00, 'swd': 0x01, 'sbw': 0x02 } try: assert typ in typei stat = dev.m3_jtagscan_get_status() if stat < SCAN_IDLE: print("Another %s scan already in progress, aborting" % types.get(stat, "pinout")) return 1 minstart, maxend = dev.m3_jtagscan_pinrange() if start_pin < minstart: print("Start pin must be at least %d, but is %d" % (minstart, start_pin)) return 1 if end_pin > maxend: print("End pin must be at most %d, but is %d" % (maxend, end_pin)) return 1 if start_pin > end_pin: print("WARN: start pin %d greater than end pin %d, swapping the order..." % (start_pin, end_pin)) end_pin, start_pin = start_pin, end_pin print("Starting %s scan..." % typ.upper()) dev.m3_jtagscan_start(typei[typ], start_pin, end_pin) stat = typei[typ] while stat < SCAN_IDLE: # TODO: timeout? # TODO: time guess? 50us*some factor*pins!/((pins-portnum)!) if stat != typei[typ]: print("Wut?!! device should be in state %d (%s) but is in %d (%s)" % (typei[typ], typ.upper(), stat, types.get(stat, '???').upper())) stat = dev.m3_jtagscan_get_status() time.sleep(0.1) sys.stdout.write('.') sys.stdout.flush() sys.stdout.write('\n') if (stat & SCAN_DONE_F) != 0: nmatches = stat & (SCAN_DONE_F - 1) print("%s scan finished (%d matches)%s" % \ (typ.upper(), nmatches, ':' if nmatches else '')) matches = None if typ == 'jtag': matches = dev.m3_jtagscan_get_result_jtag(nmatches) mat_good, mat_maybe = [], [] for e in matches: (mat_good if e.ntoggle == 0 else mat_maybe).append(e) print("Certain matches:") for i in range(len(mat_good)): print("% 2d\t%s" % (i+1, str(mat_good[i]))) print("\nPossible matches:") for i in range(len(mat_maybe)): print("% 2d\t%s" % (i+1+len(mat_good), str(mat_maybe[i]))) return 0 elif typ == 'swd': matches = dev.m3_jtagscan_get_result_swd(nmatches) else: assert False, "wut" for i in range(nmatches): print("% 2d\t%s" % (i+1, str(matches[i]))) return 0 else: print("Huh, device replied weird status %d?" % stat) return 1 except Exception as e: traceback.print_exc() print("Could not perform JTAG scan: %s" % str(e)) return 1 # --- def sump_overclock_get(dev: DPDevice) -> int: try: stat = dev.m4_sump_overclock_get() print("SUMP overclocking mode: %d" % stat) return 0 except Exception as e: print("Could not get SUMP overclocking: %s" % str(e)) return 1 def sump_overclock_set(dev: DPDevice, v: int) -> int: try: stat = dev.m4_sump_overclock_set(v) return 0 except Exception as e: traceback.print_exc() print("Could not set SUMP overclocking: %s" % str(e)) return 1