Skip to content

Commit

Permalink
Adding i2cbridge and marble_i2c regression tests to CI
Browse files Browse the repository at this point in the history
  • Loading branch information
Keith Penney committed Jan 30, 2025
1 parent d40a2c7 commit 9398cd1
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 29 deletions.
4 changes: 4 additions & 0 deletions .gitlab/ci/marble_family.gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,7 @@ marble_run:
script:
- make marble2_hwload SERIAL=39 && sleep 8 && make marble2_hwtest SERIAL=39

marble_i2c_check:
stage: test
script:
- make -C projects/test_marble_family/i2c tests
4 changes: 2 additions & 2 deletions peripheral_drivers/i2cbridge/decode.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ def decode(self, prog):
pa += 1

self.print("---- End of report ----")
return
return 0


def load_file(file_path=None, base=None):
Expand Down Expand Up @@ -241,4 +241,4 @@ def main():


if __name__ == '__main__':
main()
exit(main())
18 changes: 13 additions & 5 deletions projects/test_marble_family/i2c/Makefile
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
# A demo of Marble-specific I2C functionality

PYTHON = python3
PYTHON ?= python3

TARGETS = prog.dat prog.vh prog.h prog.json

.PHONY: all
all: $(TARGETS)

# ======= Build a program for i2c_chunk
.PHONY: tests
tests: check violations decode generic_decode

# ======= Simply build and check a program
PROG_FILE = demo_marble_i2c.py
.PHONY: check
check: $(PROG_FILE)
$(PYTHON) $<

# ======= Build a program for i2c_chunk
prog.dat: $(PROG_FILE)
$(PYTHON) $< > $@
$(PYTHON) $< p > $@

# ======= Build a memory map in Verilog format
prog.vh: $(PROG_FILE)
Expand All @@ -26,8 +34,8 @@ prog.json: $(PROG_FILE)

# ======= Test a bunch of assembler violations
BAD_FILE = demo_i2c_baddy.py
.PHONY: test
test: $(BAD_FILE)
.PHONY: violations
violations: $(BAD_FILE)
$(PYTHON) $<

# ======= Decode a program in marble context
Expand Down
2 changes: 1 addition & 1 deletion projects/test_marble_family/i2c/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,6 @@ i2cbridge tools. Note the difference in readability from the application perspe
This last test is not truly platform-specific but shows various violations of the I2C assembler rules
using the Marble platform-aware interface. None of the rules violated are specific to the platform.

`make test`
`make violations`

See `demo_i2c_baddy.py` for examples of what to avoid.
4 changes: 2 additions & 2 deletions projects/test_marble_family/i2c/demo_i2c_baddy.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def doViolations(argv):
violations[n]()
except marble_i2c.assem.I2C_Assembler_Exception as i2ce:
print(f"{i2ce}\n")
return
return 0


def violation1():
Expand Down Expand Up @@ -113,4 +113,4 @@ def violation6():


if __name__ == "__main__":
doViolations(sys.argv)
exit(doViolations(sys.argv))
23 changes: 19 additions & 4 deletions projects/test_marble_family/i2c/demo_marble_i2c.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,17 +109,32 @@ def build_prog(argv):
m.pause(4096) # Pause for roughly 0.24ms
m.jump(jump_n) # Jump back to loop start

# ======= End Program =======
# ======= Demo Functionality =======
if len(argv) > 1:
op = argv[1]
if len(argv) > 2:
offset = _int(argv[2])
else:
offset = 0
m.write_reg_map(offset=offset, style=op)
if op == 'p':
m.write_program()
else:
m.write_reg_map(offset=offset, style=op)
return 0

# ======= (Anti-)Regression Test =======
rval = 0
errstr = None
try:
m.check_program()
except marble_i2c.assem.I2C_Assembler_Exception as err:
rval = 1
errstr = str(err)
if rval == 0:
print("PASS")
else:
m.write_program()
return
print("FAIL: {}".format(errstr))
return rval


if __name__ == "__main__":
Expand Down
46 changes: 35 additions & 11 deletions projects/test_marble_family/i2c/marble_i2c.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,13 @@ class MarbleI2C():
_ina219_map = {0: "U17", 1: "U32", 2: "U57"}

# Build a 2D list from the map
_a = []
_ic_list = []
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_list.append((ic_name, ic_addr, branch_name, ch, mux_name, mux_addr))

# ========= IC-Specific Information =================
# U34 (PCAL9555) I2C GPIO expander
Expand Down Expand Up @@ -172,17 +172,41 @@ def _inherit(self):

def _associate(self):
"""[private] Build a 2D list from the map"""
if hasattr(self, "_a"):
if hasattr(self, "_ic_list"):
return
self._a = []
self._ic_list = []
for mux, tree in self._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():
self._a.append((ic_name, ic_addr, branch_name, ch, mux_name, mux_addr))
self._ic_list.append((ic_name, ic_addr, branch_name, ch, mux_name, mux_addr))
return

@property
def ic_list(self):
"""Returns list of tuple entries:
(ic_name, ic_addr, branch_name, branch, mux_name, mux_addr)
string ic_name: Refdes (i.e. "U5") from schematic
int ic_addr: I2C address of the IC (in 8-bit format)
string branch_name: The name of the I2C branch the IC lives on (i.e. "APP")
int branch: The index of the branch (how it is selected by the bus mux)
string mux_name: The refdes of the bus mux that leads to this IC.
int mux_addr: The I2C address of the bus mux that leads to this IC.
"""
return self._ic_list

@property
def ic_dict(self):
"""Returns dict of tuple entries:
ic_name: (ic_addr, branch_name, branch, mux_name, mux_addr)
See property 'ic_list' for description of each item.
"""
dd = {}
for entry in self._ic_list:
dd[entry[0]] = entry[1:]
return dd

def _busmux(self, mux_addr, mux_ch):
"""[private] Select a channel with the bus multiplexer at address mux_addr."""
if self._s is None:
Expand Down Expand Up @@ -222,7 +246,7 @@ def get_mux_dict(cls, mux_name=None):
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 cls._a:
for _l in cls._ic_list:
name = _l[0]
addr = _l[1]
ics.append((name, addr))
Expand All @@ -235,7 +259,7 @@ def get_i2c_addr(cls, ic_name):
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 cls._a:
for _l in cls._ic_list:
if ic_name == _l[0]:
return _l[1]
return None
Expand All @@ -247,7 +271,7 @@ def get_i2c_name(cls, i2c_addr):
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 cls._a:
for _l in cls._ic_list:
if i2c_addr == _l[1]:
return _l[0]
return None
Expand All @@ -264,7 +288,7 @@ def select_ic(self, ic_name):
if ic_name == busmux_ic:
# We can always talk to the busmux
return busmux_addr
for nic in self._a:
for nic in self._ic_list:
_ic_name, ic_addr, branch_name, ch, mux_name, mux_addr = nic
if ic_name.lower().strip() == _ic_name.lower().strip():
# If we found a match, mux to it
Expand All @@ -279,7 +303,7 @@ def select_branch(self, branch):
Returns int channel number (0-7) that was selected or None if 'branch' does not match
any of the above.
"""
for nic in self._a:
for nic in self._ic_list:
ic_name, ic_addr, branch_name, ch, mux_name, mux_addr = nic
if branch_name.lower().strip() == branch.lower().strip():
# If we found a match, mux to it
Expand All @@ -293,7 +317,7 @@ def get_addr(cls, 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 cls._a:
for nic in cls._ic_list:
_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
8 changes: 4 additions & 4 deletions projects/test_marble_family/i2c/marble_i2c_decoder.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def marble_write(devaddr, nbytes, cmd_table):
msg = f"Busmux - bitmask: 0b{bitmask:08b} Selected {seltext}"
if msg is None:
data = []
for _l in marble._a:
for _l in marble.ic_list:
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):
Expand All @@ -81,7 +81,7 @@ def marble_read(devaddr, nbytes, cmd_table):
for muxname, address in marble.get_muxes():
if devaddr == address:
msg = "Busmux - Readback"
for _l in marble._a:
for _l in marble.ic_list:
ic_name, ic_addr, branch_name, ch, mux_name, mux_addr = _l
if devaddr == ic_addr and ((1 << ch) & bus_bitmask):
s = "" if nbytes == 1 else "s"
Expand All @@ -93,7 +93,7 @@ def marble_write_rpt(devaddr, memaddr, nbytes, cmd_table):
data = []
msg = None
inc = 0
for _l in marble._a:
for _l in marble.ic_list:
ic_name, ic_addr, branch_name, ch, mux_name, mux_addr = _l
if devaddr == ic_addr and ((1 << ch) & bus_bitmask):
if nbytes == 0:
Expand All @@ -113,4 +113,4 @@ def marble_write_rpt(devaddr, memaddr, nbytes, cmd_table):
# =============================================================================

if __name__ == "__main__":
_decode.main()
exit(_decode.main())

0 comments on commit 9398cd1

Please sign in to comment.