From a129cf829796bb27e27e259e1bcaa9338143cb74 Mon Sep 17 00:00:00 2001 From: Keith Penney Date: Thu, 19 Dec 2024 15:21:54 -0800 Subject: [PATCH] Exposing more I2C functions for external/inherited use --- peripheral_drivers/i2cbridge/assem.py | 4 ++ peripheral_drivers/i2cbridge/decode.py | 50 ++++++++++++++----- projects/test_marble_family/i2c/marble_i2c.py | 29 ++++++++--- .../i2c/marble_i2c_decoder.py | 23 +++++---- 4 files changed, 76 insertions(+), 30 deletions(-) diff --git a/peripheral_drivers/i2cbridge/assem.py b/peripheral_drivers/i2cbridge/assem.py index f5de45d3e..5b2a19bc2 100644 --- a/peripheral_drivers/i2cbridge/assem.py +++ b/peripheral_drivers/i2cbridge/assem.py @@ -654,6 +654,10 @@ def write_reg_map(self, fd=sys.stdout, offset=0, style="v", filename=None): fd.write(post) return + def get_regmap(self): + """Return dict of {regname: (results_memory_offset, number_of_bytes)}""" + return self._memdict + class I2C_Assembler_Exception(Exception): def __init__(self, s): diff --git a/peripheral_drivers/i2cbridge/decode.py b/peripheral_drivers/i2cbridge/decode.py index 0aeaae9c6..71ecd930d 100644 --- a/peripheral_drivers/i2cbridge/decode.py +++ b/peripheral_drivers/i2cbridge/decode.py @@ -6,7 +6,22 @@ from datetime import datetime +def _int(x): + try: + return int(x) + except ValueError: + pass + try: + return int(x, 16) + except ValueError: + pass + return int(x, 2) + + # ========================= Platform-Specific Overrides ======================= +break_on_stop = True + + def platform_write(devaddr, nbytes, cmd_table): return None, 0 @@ -20,21 +35,29 @@ def platform_write_rpt(devaddr, memaddr, nbytes, cmd_table): # ============================================================================= -def decode(argv): +def decode_file(argv): if len(argv) > 1: filename = argv[1] else: print("No filename provided") return - cmd_table = load_file(filename) + prog = load_file(filename) + return decode(prog, filename=prog.name) + + +def decode(prog, filename=None): + cmd_table = iter(prog) pa = 0 if not cmd_table: return else: - report_file = f"File {cmd_table.name} - {datetime.now()}\n---- Start of report ----\n" + report_file = "" + if filename is not None: + report_file = f"File {filename} - {datetime.now()}\n" + report_file += "---- Start of report ----\n" report_file += "Prog Address : Cmd Byte : [op_code n_code] -> Description and data\n" for idx, cmd_line in enumerate(cmd_table): - cmd_byte = int(cmd_line[:2], 16) + cmd_byte = _int(cmd_line) op_code = cmd_byte >> 5 n_code = cmd_byte & 0x1f @@ -42,6 +65,9 @@ def decode(argv): if op_code == 0: # special if n_code == 0: report_file += "STOP (sleep)\n" + if break_on_stop: + report_file += "Terminating decoding due to break_on_stop policy\n" + break elif n_code == 2: report_file += "Result buffer flip\n" elif n_code == 3: @@ -52,7 +78,7 @@ def decode(argv): elif op_code == 1: # read dlen = n_code-1 - devaddr = int(next(cmd_table)[:2], 16) + devaddr = _int(next(cmd_table)) pa += 1 s, inc = platform_read(devaddr, dlen, cmd_table) if s is not None: @@ -64,7 +90,7 @@ def decode(argv): elif op_code == 2: # write # n_code = 1 + addr_bytes + len(data) nbytes = n_code-1 - devaddr = int(next(cmd_table)[:2], 16) + devaddr = _int(next(cmd_table)) pa += 1 s, inc = platform_write(devaddr, nbytes, cmd_table) if s is not None: @@ -73,7 +99,7 @@ def decode(argv): else: report_file += f"Write - dev_addr: 0x{devaddr:02x} - mem_addr+data:" for j in range(nbytes): - data = int(next(cmd_table)[:2], 16) + data = _int(next(cmd_table)) pa += 1 report_file += f" 0x{data:02x}" report_file += '\n' @@ -81,11 +107,11 @@ def decode(argv): elif op_code == 3: # write followed by repeated start addr_bytes = n_code-1 dlen = n_code-2 - devaddr = int(next(cmd_table)[:2], 16) - memaddr = int(next(cmd_table)[:2], 16) + devaddr = _int(next(cmd_table)) + memaddr = _int(next(cmd_table)) pa += 2 if addr_bytes == 2: - memaddr = (memaddr << 8) + int(next(cmd_table)[:2], 16) + memaddr = (memaddr << 8) + _int(next(cmd_table)) pa += 1 s, inc = platform_write_rpt(devaddr, memaddr, dlen, cmd_table) if s is not None: @@ -95,7 +121,7 @@ def decode(argv): report_file += f"Write - dev_addr: 0x{devaddr:02x} - mem_addr:" + \ f" 0x{memaddr:04x} - START - data:" for j in range(n_code-2): - data = int(next(cmd_table)[:2], 16) + data = _int(next(cmd_table)) pa += 1 report_file += f" 0x{data:02x}" report_file += '\n' @@ -160,4 +186,4 @@ def is_plaintext(file): if __name__ == '__main__': import sys - decode(sys.argv) + decode_file(sys.argv) diff --git a/projects/test_marble_family/i2c/marble_i2c.py b/projects/test_marble_family/i2c/marble_i2c.py index d9d0c8bc6..b3d9cc31a 100644 --- a/projects/test_marble_family/i2c/marble_i2c.py +++ b/projects/test_marble_family/i2c/marble_i2c.py @@ -67,6 +67,15 @@ class MarbleI2C(): # INA219 index : IC name _ina219_map = {0: "U17", 1: "U32", 2: "U57"} + # Build a 2D list from the map + _a = [] + for mux, tree in _i2c_map.items(): + mux_name, mux_addr = mux + for ch, branch in tree.items(): + branch_name, branch_dict = branch + for ic_name, ic_addr in branch_dict.items(): + _a.append((ic_name, ic_addr, branch_name, ch, mux_name, mux_addr)) + # ========= IC-Specific Information ================= # U34 (PCAL9555) I2C GPIO expander # Unused pins are set as input and have internal weak pullups @@ -209,33 +218,36 @@ def get_mux_dict(cls, mux_name=None): return tree return {} - def get_ics(self): + @classmethod + def get_ics(cls): """Returns a list of tuples (name_str, i2c_address_int) for all ICs in the I2C map.""" ics = [] - for _l in self._a: + for _l in cls._a: name = _l[0] addr = _l[1] ics.append((name, addr)) return ics - def get_i2c_addr(self, ic_name): + @classmethod + def get_i2c_addr(cls, ic_name): """Get the I2C address of IC with name 'ic_name' Params: string ic_name: Any valid IC name in the I2C map Returns int I2C address if 'ic_name' is found in the I2C map, otherwise None. """ - for _l in self._a: + for _l in cls._a: if ic_name == _l[0]: return _l[1] return None - def get_i2c_name(self, i2c_addr): + @classmethod + def get_i2c_name(cls, i2c_addr): """Get the name of IC with I2C address 'i2c_addr' Params: int i2c_addr: I2C address of the desired IC (0-255). Returns string IC name if 'i2c_addr' is found in the I2C map, otherwise None. """ - for _l in self._a: + for _l in cls._a: if i2c_addr == _l[1]: return _l[0] return None @@ -271,12 +283,13 @@ def select_branch(self, branch): return ch return None - def get_addr(self, ic_name): + @classmethod + def get_addr(cls, ic_name): """Get the I2C address of IC given by string 'ic_name' Params: string ic_name: Any valid IC name in the I2C map Returns I2C address (int) if 'ic_name' is found in the I2C map, otherwise None.""" - for nic in self._a: + for nic in cls._a: _ic_name, ic_addr, branch_name, ch, mux_name, mux_addr = nic if ic_name.lower().strip() == _ic_name.lower().strip(): return ic_addr diff --git a/projects/test_marble_family/i2c/marble_i2c_decoder.py b/projects/test_marble_family/i2c/marble_i2c_decoder.py index df5b5c26f..5dfd20817 100644 --- a/projects/test_marble_family/i2c/marble_i2c_decoder.py +++ b/projects/test_marble_family/i2c/marble_i2c_decoder.py @@ -6,18 +6,19 @@ _decode_path = "../../../peripheral_drivers/i2cbridge" try: - import decode + import decode as _decode except ImportError: try: - from i2cbridge import decode + from i2cbridge import decode as _decode except ImportError: try: sys.path.append(_decode_path) - import decode + import decode as _decode except ImportError: print("Cannot import module 'decode'. Set PYTHONPATH to bedrock/peripheral_drivers/i2cbridge") sys.exit(1) +_int = _decode._int import marble_i2c @@ -57,7 +58,7 @@ def marble_write(devaddr, nbytes, cmd_table): inc = 0 for muxname, address in marble.get_muxes(): if devaddr == address: - bitmask = int(next(cmd_table), 16) + bitmask = _int(next(cmd_table)) seltext = _selected(bitmask) inc += 1 msg = f"Busmux - bitmask: 0b{bitmask:08b} Selected {seltext}" @@ -67,7 +68,7 @@ def marble_write(devaddr, nbytes, cmd_table): ic_name, ic_addr, branch_name, ch, mux_name, mux_addr = _l if devaddr == ic_addr and ((1 << ch) & bus_bitmask): for n in range(nbytes): - data.append(int(next(cmd_table), 16)) + data.append(_int(next(cmd_table))) inc += 1 msg = "Write to {} - data: {}".format(ic_name, [hex(m) for m in data]) return msg, inc @@ -99,19 +100,21 @@ def marble_write_rpt(devaddr, memaddr, nbytes, cmd_table): msg = "Read from {} offset 0x{:x} - START".format(ic_name, memaddr) else: for n in range(nbytes): - data.append(int(next(cmd_table), 16)) + data.append(_int(next(cmd_table))) inc += 1 msg = "Write to {} offset 0x{:x} - data: {}".format(ic_name, memaddr, [hex(m) for m in data]) return msg, inc # ====================== Override Generic Platform Hooks ====================== -decode.platform_write = marble_write -decode.platform_read = marble_read -decode.platform_write_rpt = marble_write_rpt +_decode.platform_write = marble_write +_decode.platform_read = marble_read +_decode.platform_write_rpt = marble_write_rpt # ============================================================================= +# Expose the (now platform-specific) 'decode' function in the 'decode' module +decode = _decode.decode if __name__ == "__main__": import sys - decode.decode(sys.argv) + _decode.decode_file(sys.argv)