Skip to content

Commit

Permalink
Exposing more I2C functions for external/inherited use
Browse files Browse the repository at this point in the history
  • Loading branch information
Keith Penney committed Dec 19, 2024
1 parent 4c60b9c commit a129cf8
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 30 deletions.
4 changes: 4 additions & 0 deletions peripheral_drivers/i2cbridge/assem.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down
50 changes: 38 additions & 12 deletions peripheral_drivers/i2cbridge/decode.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -20,28 +35,39 @@ 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

report_file += f"{pa:03x}: {cmd_byte:02x} : [{op_code:03b} {n_code:05b}] -> "
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:
Expand All @@ -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:
Expand All @@ -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:
Expand All @@ -73,19 +99,19 @@ 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'

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:
Expand All @@ -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'
Expand Down Expand Up @@ -160,4 +186,4 @@ def is_plaintext(file):

if __name__ == '__main__':
import sys
decode(sys.argv)
decode_file(sys.argv)
29 changes: 21 additions & 8 deletions projects/test_marble_family/i2c/marble_i2c.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
23 changes: 13 additions & 10 deletions projects/test_marble_family/i2c/marble_i2c_decoder.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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}"
Expand All @@ -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
Expand Down Expand Up @@ -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)

0 comments on commit a129cf8

Please sign in to comment.