浏览代码

gw.py pin: Allow a pin to be manually set to specified level.
Fixes #20

Keir Fraser 5 年之前
父节点
当前提交
88b3af0076
共有 5 个文件被更改,包括 87 次插入14 次删除
  1. 4 1
      inc/cdc_acm_protocol.h
  2. 48 0
      scripts/greaseweazle/tools/pin.py
  3. 22 12
      scripts/greaseweazle/usb.py
  4. 1 1
      scripts/gw.py
  5. 12 0
      src/floppy.c

+ 4 - 1
inc/cdc_acm_protocol.h

@@ -49,7 +49,9 @@
 #define CMD_DESELECT       13
 /* CMD_SET_BUS_TYPE, length=3, bus_type. Set the bus type. */
 #define CMD_SET_BUS_TYPE   14
-#define CMD_MAX            14
+/* CMD_SET_PIN, length=4, pin#, level. */
+#define CMD_SET_PIN        15
+#define CMD_MAX            15
 
 
 /*
@@ -73,6 +75,7 @@
 #define ACK_NO_UNIT         7
 #define ACK_NO_BUS          8
 #define ACK_BAD_UNIT        9
+#define ACK_BAD_PIN        10
 
 
 /*

+ 48 - 0
scripts/greaseweazle/tools/pin.py

@@ -0,0 +1,48 @@
+# greaseweazle/tools/pin.py
+#
+# Greaseweazle control script: Set a floppy interface pin to specified level.
+#
+# Written & released by Keir Fraser <keir.xen@gmail.com>
+#
+# This is free and unencumbered software released into the public domain.
+# See the file COPYING for more details, or visit <http://unlicense.org>.
+
+import sys, argparse
+
+from greaseweazle.tools import util
+from greaseweazle import usb as USB
+
+def level(letter):
+    levels = { 'H': True, 'L': False }
+    if not letter.upper() in levels:
+        raise argparse.ArgumentTypeError("invalid pin level: '%s'" % letter)
+    return levels[letter.upper()]
+
+def main(argv):
+
+    parser = argparse.ArgumentParser(
+        formatter_class=argparse.ArgumentDefaultsHelpFormatter)
+    parser.add_argument("pin", type=int,
+                        help="pin number")
+    parser.add_argument("level", type=level,
+                        help="pin level (H,L)")
+    parser.add_argument("device", nargs="?", default="auto",
+                        help="serial device")
+    parser.prog += ' ' + argv[1]
+    args = parser.parse_args(argv[2:])
+
+    try:
+        usb = util.usb_open(args.device)
+        usb.set_pin(args.pin, args.level)
+        print("Pin %u is set %s" %
+              (args.pin, ("Low (0v)", "High (5v)")[args.level]))
+    except USB.CmdError as error:
+        print("Command Failed: %s" % error)
+
+
+if __name__ == "__main__":
+    main(sys.argv)
+
+# Local variables:
+# python-indent: 4
+# End:

+ 22 - 12
scripts/greaseweazle/usb.py

@@ -32,6 +32,7 @@ class Cmd:
     Select          = 12
     Deselect        = 13
     SetBusType      = 14
+    SetPin          = 15
     str = {
         GetInfo: "GetInfo",
         Update: "Update",
@@ -47,22 +48,24 @@ class Cmd:
         SwitchFwMode: "SwitchFwMode",
         Select: "Select",
         Deselect: "Deselect",
-        SetBusType: "SetBusType"
+        SetBusType: "SetBusType",
+        SetPin: "SetPin"
     }
 
 
 ## Command responses/acknowledgements
 class Ack:
-    Okay            = 0
-    BadCommand      = 1
-    NoIndex         = 2
-    NoTrk0          = 3
-    FluxOverflow    = 4
-    FluxUnderflow   = 5
-    Wrprot          = 6
-    NoUnit          = 7
-    NoBus           = 8
-    BadUnit         = 9
+    Okay            =  0
+    BadCommand      =  1
+    NoIndex         =  2
+    NoTrk0          =  3
+    FluxOverflow    =  4
+    FluxUnderflow   =  5
+    Wrprot          =  6
+    NoUnit          =  7
+    NoBus           =  8
+    BadUnit         =  9
+    BadPin          = 10
     str = {
         Okay: "Okay",
         BadCommand: "Bad Command",
@@ -73,7 +76,8 @@ class Ack:
         Wrprot: "Disk is Write Protected",
         NoUnit: "No drive unit selected",
         NoBus: "No bus type (eg. Shugart, IBM/PC) specified",
-        BadUnit: "Bad unit number"
+        BadUnit: "Bad unit number",
+        BadPin: "Not a modifiable pin"
     }
 
 
@@ -177,6 +181,12 @@ class Unit:
         self._send_cmd(struct.pack("3B", Cmd.SetBusType, 3, type))
 
 
+    ## set_pin:
+    ## Set a pin level.
+    def set_pin(self, pin, level):
+        self._send_cmd(struct.pack("4B", Cmd.SetPin, 4, pin, int(level)))
+
+
     ## drive_select:
     ## Select the specified drive unit.
     def drive_select(self, unit):

+ 1 - 1
scripts/gw.py

@@ -12,7 +12,7 @@
 import sys
 import importlib
 
-actions = [ 'read', 'write', 'delays', 'update' ]
+actions = [ 'read', 'write', 'delays', 'update', 'pin' ]
 argv = sys.argv
 
 if len(argv) < 2 or argv[1] not in actions:

+ 12 - 0
src/floppy.c

@@ -854,6 +854,18 @@ static void process_command(void)
             goto bad_command;
         break;
     }
+    case CMD_SET_PIN: {
+        uint8_t pin = u_buf[2];
+        uint8_t level = u_buf[3];
+        if ((len != 4) || (level & ~1))
+            goto bad_command;
+        if (pin != 2) {
+            u_buf[1] = ACK_BAD_PIN;
+            goto out;
+        }
+        gpio_write_pin(gpio_densel, pin_densel, level);
+        break;
+    }
     case CMD_SWITCH_FW_MODE: {
         uint8_t mode = u_buf[2];
         if ((len != 3) || (mode & ~1))