From 9f77e9764b54a64296613d7ac52645adf2ab0514 Mon Sep 17 00:00:00 2001 From: sys64738 Date: Sat, 12 Jun 2021 21:55:09 +0200 Subject: [PATCH] update README, make dmctl usable --- README.md | 36 +++++++++++++++++++++++++++++++++--- dmctl.py | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 83 insertions(+), 8 deletions(-) mode change 100644 => 100755 dmctl.py diff --git a/README.md b/README.md index f8281dc..410176c 100644 --- a/README.md +++ b/README.md @@ -81,13 +81,15 @@ The pin mapping for the RP2040 is as follows: | <end>| <bottom> | <bottom> | <end>| On the RP2040, two USB CDC interfaces are exposed: the first is the UART -interface, the second is for Serprog. If you have no other USB CDC devices, +interface, the second is for Serprog. If you have no other USB-CDC intefaces, these will be `/dev/ttyACM0` and `/dev/ttyACM1`, respectively. The UART pins are for connecting to the device to be debugged, the data is echoed back over the USB CDC interface (typically a `/dev/ttyACMx` device on -Linux). If you want to get stdio readout on your computer, connect GP0 to GP5, -and GP1 to GP4. +Linux). If you want to get stdio readout of this program on your computer, +connect GP0 to GP5, and GP1 to GP4, or alternatively, use the +`USE_USBCDC_FOR_STDIO` CMake flag, which adds an extra USB-CDC interface for +which stdio is used exclusively, while disabling stdio on the UART. In SWD mode, the pin mapping is entirely as with the standard Picoprobe setup, as described in Chapter 5 and Appendix A of [Getting Started with Raspberry Pi @@ -111,6 +113,34 @@ Different serial speeds can be used, too. Serprog support is *techincally* untested, as in it does output the correct SPI commands as seen by my logic analyzer, but I don't have a SPI flash chip to test it on. +### Runtime configuration + +Several settings can be applied at runtime, using the `dmctl` Python script. +Settings are communicated over the Serprog USB serial port. + +The currently implemented options are: +- `ctsrts`: Enable/disable CTS/RTS-based hardware flow control for the UART port + +``` +usage: dmctl [-h] [-v] [--ctsrts [CTSRTS]] tty + +Runtime configuration control for DapperMime-JTAG + +positional arguments: + tty Path to DapperMime-JTAG Serprog UART device + +optional arguments: + -h, --help show this help message and exit + -v, --verbose Verbose logging (for this utility) + --ctsrts [CTSRTS] Enable or disable CTS/RTS flow control (--ctsrts [true|false]) +``` + +example: + +``` +$ ./dmctl.py /dev/ttyACM1 --ctsrts true +``` + ## License TinyUSB is licensed under the [MIT license](https://opensource.org/licenses/MIT). diff --git a/dmctl.py b/dmctl.py old mode 100644 new mode 100755 index 4b0db08..914e849 --- a/dmctl.py +++ b/dmctl.py @@ -1,8 +1,17 @@ #!/usr/bin/env python3 -import serial, struct +import argparse, serial, struct from typing import * +class RTOpt(NamedTuple): + type: bool + optid: int + desc: str + +option_table = { + 'ctsrts': RTOpt(bool, 1, "Enable or disable CTS/RTS flow control (--ctsrts [true|false])") +} + S_ACK = b'\x06' S_NAK = b'\x15' @@ -13,7 +22,13 @@ S_CMD_Q_PGMNAME = b'\x03' S_CMD_SYNCNOP = b'\x10' S_CMD_MAGIC_SETTINGS = b'\x53' -def do_xfer(cmd:int, arg:int, port: str, baudrate:int=115200) -> Optional[int]: +def val2byte(t, v) -> int: + if t == bool: + return 1 if v else 0 + + assert False, "unimplemented type %s" % str(t) + +def do_xfer(args, cmd:int, arg:int, port: str, baudrate:int=115200) -> Optional[int]: with serial.Serial(port, baudrate, timeout=1) as ser: cmdmap = [0]*32 syncok = False @@ -60,7 +75,7 @@ def do_xfer(cmd:int, arg:int, port: str, baudrate:int=115200) -> Optional[int]: print("q_pgmname failed") else: name = ser.read(16).decode('utf-8') - print("programmer is '%s'" % name) + if args.verbose: print("programmer is '%s'" % name) ser.write(S_CMD_MAGIC_SETTINGS) ser.write(bytes([cmd,arg])) @@ -72,6 +87,36 @@ def do_xfer(cmd:int, arg:int, port: str, baudrate:int=115200) -> Optional[int]: print("settings command failed") return None -do_xfer(1, 1, "/dev/ttyACM1") -do_xfer(1, 0, "/dev/ttyACM1") +def main(): + parser = argparse.ArgumentParser(prog="dmctl", + description="Runtime configuration control for DapperMime-JTAG") + + parser.add_argument('tty', type=str, nargs=1, #'?', #default="/dev/ttyACM1", + help="Path to DapperMime-JTAG Serprog UART device"#+\ + #" [/dev/ttyACM1]" + ) + + parser.add_argument('-v', '--verbose', default=False, action='store_true', + help="Verbose logging (for this utility)") + + for k, v in option_table.items(): + parser.add_argument('--%s'%k, type=v.type, nargs='?', default=None, + help=v.desc) + + args = parser.parse_args() + + for k, v in option_table.items(): + if args.__dict__[k] is not None: + resp = do_xfer(args, v.optid, val2byte(v.type, args.__dict__[k]), args.tty) + if resp is None: + return 1 + if args.verbose: print("-> %d" % resp) + + return 0 + +#do_xfer(1, 1, "/dev/ttyACM1") +#do_xfer(1, 0, "/dev/ttyACM1") + +if __name__ == '__main__': + main()