Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: whitequark/glasgow
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: f7e0ee0919e1
Choose a base ref
...
head repository: whitequark/glasgow
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: f6279acbec46
Choose a head ref
  • 3 commits
  • 3 files changed
  • 1 contributor

Commits on Mar 8, 2019

  1. applet.interface.i2c_master: use argparse subparsers.

    Instead of mutually exclusive groups.
    whitequark committed Mar 8, 2019
    Copy the full SHA
    9030521 View commit details
  2. applet.memory.25x: remove default for ADDRESS and LENGTH arguments.

    These need to be specified explicitly anyway in virtually all cases.
    whitequark committed Mar 8, 2019
    Copy the full SHA
    2698dfd View commit details
  3. applet.memory.24x: use argparse subparsers.

    Instead of mutually exclusive groups.
    
    Also, handle errors.
    whitequark committed Mar 8, 2019
    Copy the full SHA
    f6279ac View commit details
Showing with 77 additions and 39 deletions.
  1. +22 −19 software/glasgow/applet/interface/i2c_master/__init__.py
  2. +52 −17 software/glasgow/applet/memory/_24x/__init__.py
  3. +3 −3 software/glasgow/applet/memory/_25x/__init__.py
41 changes: 22 additions & 19 deletions software/glasgow/applet/interface/i2c_master/__init__.py
Original file line number Diff line number Diff line change
@@ -285,40 +285,43 @@ async def run(self, device, args):

@classmethod
def add_interact_arguments(cls, parser):
parser.add_argument(
"--scan-device-id", action="store_true", default=False,
help="read device ID from devices responding to scan")

g_operation = parser.add_mutually_exclusive_group(required=True)
g_operation.add_argument(
"--scan-read", action="store_true", default=False,
help="scan all possible I2C read addresses")
g_operation.add_argument(
"--scan-write", action="store_true", default=False,
help="scan all possible I2C write addresses")
g_operation.add_argument(
"--repl", action="store_true", default=False,
help="drop into Python shell; use `i2c_iface` to communicate")
p_operation = parser.add_subparsers(dest="operation", metavar="OPERATION", required=True)

def add_scan_id_argument(parser):
parser.add_argument(
"--device-id", action="store_true", default=False,
help="read device ID from devices responding to scan")

p_scan_read = p_operation.add_parser(
"scan-read", help="scan all possible I2C read addresses")
add_scan_id_argument(p_scan_read)

p_scan_write = p_operation.add_parser(
"scan-write", help="scan all possible I2C write addresses")
add_scan_id_argument(p_scan_write)

p_repl = p_operation.add_parser(
"repl", help="drop into Python shell; use `i2c_iface` to communicate")

async def interact(self, device, args, i2c_iface):
if args.scan_read or args.scan_write:
if args.operation in ("scan-read", "scan-write"):
# Don't scan reserved I2C addresses.
for addr in range(0b0001_000, 0b1111_000):
responded = False
if args.scan_read:
if args.operation == "scan-read":
# We need to read at least one byte in order to transmit a NAK bit
# so that the addressed device releases SDA.
if await i2c_iface.read(addr, 1, stop=True) is not None:
self.logger.info("scan found read address %s",
"{:#09b}".format(addr))
responded = True
if args.scan_write:
if args.operation == "scan-write":
if await i2c_iface.write(addr, [], stop=True) is True:
self.logger.info("scan found write address %s",
"{:#09b}".format(addr))
responded = True

if responded and args.scan_device_id:
if responded and args.device_id:
device_id = await i2c_iface.device_id(addr)
if device_id is None:
self.logger.warning("device %s did not acknowledge Device ID", bin(addr))
@@ -327,7 +330,7 @@ async def interact(self, device, args, i2c_iface):
self.logger.info("device %s ID: manufacturer %s, part %s, revision %s",
bin(addr), bin(manufacturer), bin(part_ident), bin(revision))

if args.repl:
if args.operation == "repl":
await AsyncInteractiveConsole(locals={"i2c_iface":i2c_iface}).interact()

# -------------------------------------------------------------------------------------------------
69 changes: 52 additions & 17 deletions software/glasgow/applet/memory/_24x/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import logging
import argparse

from ...interface.i2c_master import I2CMasterApplet
from ... import *
@@ -104,23 +105,57 @@ async def run(self, device, args):

@classmethod
def add_interact_arguments(cls, parser):
parser.add_argument(
"-a", "--address", type=int, metavar="ADDR", default=0,
help="first memory address of the read or write operation")
g_operation = parser.add_mutually_exclusive_group(required=True)
g_operation.add_argument(
"-r", "--read", type=int, metavar="SIZE",
help="read SIZE bytes starting at ADDR")
def hex(arg): return bytes.fromhex(arg)
g_operation.add_argument(
"-w", "--write", type=hex, metavar="DATA",
help="write hex bytes DATA starting at ADDR")
def address(arg):
return int(arg, 0)
def length(arg):
return int(arg, 0)
def hex_bytes(arg):
return bytes.fromhex(arg)

p_operation = parser.add_subparsers(dest="operation", metavar="OPERATION", required=True)

p_read = p_operation.add_parser(
"read", help="read memory")
p_read.add_argument(
"address", metavar="ADDRESS", type=address,
help="read memory starting at address ADDRESS, with wraparound")
p_read.add_argument(
"length", metavar="LENGTH", type=length,
help="read LENGTH bytes from memory")
p_read.add_argument(
"-f", "--file", metavar="FILENAME", type=argparse.FileType("wb"),
help="write memory contents to FILENAME")

p_write = p_operation.add_parser(
"write", help="write memory")
p_write.add_argument(
"address", metavar="ADDRESS", type=address,
help="write memory starting at address ADDRESS")
g_data = p_write.add_mutually_exclusive_group(required=True)
g_data.add_argument(
"-d", "--data", metavar="DATA", type=hex_bytes,
help="write memory with DATA as hex bytes")
g_data.add_argument(
"-f", "--file", metavar="FILENAME", type=argparse.FileType("rb"),
help="write memory with contents of FILENAME")

async def interact(self, device, args, m24x_iface):
if args.read is not None:
result = await m24x_iface.read(args.address, args.read)
if result is not None:
print(result.hex())
if args.operation == "read":
data = await m24x_iface.read(args.address, args.length)
if data is None:
raise GlasgowAppletError("memory did not acknowledge read")

if args.file:
args.file.write(data)
else:
print(data.hex())

if args.operation == "write":
if args.data is not None:
data = args.data
if args.file is not None:
data = args.file.read()

elif args.write is not None:
await m24x_iface.write(args.address, args.write)
success = await m24x_iface.write(args.address, data)
if not success:
raise GlasgowAppletError("memory did not acknowledge write")
6 changes: 3 additions & 3 deletions software/glasgow/applet/memory/_25x/__init__.py
Original file line number Diff line number Diff line change
@@ -270,10 +270,10 @@ def bits(arg):

def add_read_arguments(parser):
parser.add_argument(
"address", metavar="ADDRESS", type=address, default=0,
"address", metavar="ADDRESS", type=address,
help="read memory starting at address ADDRESS, with wraparound")
parser.add_argument(
"length", metavar="LENGTH", type=length, default=0,
"length", metavar="LENGTH", type=length,
help="read LENGTH bytes from memory")
parser.add_argument(
"-f", "--file", metavar="FILENAME", type=argparse.FileType("wb"),
@@ -289,7 +289,7 @@ def add_read_arguments(parser):

def add_program_arguments(parser):
parser.add_argument(
"address", metavar="ADDRESS", type=address, default=0,
"address", metavar="ADDRESS", type=address,
help="program memory starting at address ADDRESS")
g_data = parser.add_mutually_exclusive_group(required=True)
g_data.add_argument(