فهرست منبع

python: Move retry loops into read/write-track usb methods

Keir Fraser 5 سال پیش
والد
کامیت
ee02d5d0a8
2فایلهای تغییر یافته به همراه55 افزوده شده و 51 حذف شده
  1. 52 22
      scripts/greaseweazle/usb.py
  2. 3 29
      scripts/gw.py

+ 52 - 22
scripts/greaseweazle/usb.py

@@ -185,9 +185,9 @@ class Unit:
         return flux[:-1]
 
 
-    ## encode_flux:
+    ## _encode_flux:
     ## Convert the given flux timings into an encoded data stream.
-    def encode_flux(self, flux):
+    def _encode_flux(self, flux):
         dat = bytearray()
         for val in flux:
             if val == 0:
@@ -209,9 +209,9 @@ class Unit:
         return dat
 
 
-    ## read_track:
-    ## Read and decode flux and index timings for the current track.
-    def read_track(self, nr_revs):
+    ## _read_track:
+    ## Private helper which issues command requests to Greaseweazle.
+    def _read_track(self, nr_revs):
 
         # Request and read all flux timings for this track.
         dat = bytearray()
@@ -222,12 +222,29 @@ class Unit:
             if dat[-1] == 0:
                 break
 
-        # Check flux status. We bail if there was an error.
-        try:
-            self._send_cmd(struct.pack("2B", Cmd.GetFluxStatus, 2))
-        except CmdError as error:
-            del dat
-            return error.code, None
+        # Check flux status. An exception is raised if there was an error.
+        self._send_cmd(struct.pack("2B", Cmd.GetFluxStatus, 2))
+
+        return dat
+
+
+    ## read_track:
+    ## Read and decode flux and index timings for the current track.
+    def read_track(self, nr_revs, nr_retries=5):
+
+        retry = 0
+        while True:
+            try:
+                dat = self._read_track(nr_revs)
+            except CmdError as error:
+                # An error occurred. We may retry on transient overflows.
+                if error.code == Ack.FluxOverflow and retry < nr_retries:
+                    retry += 1
+                else:
+                    raise error
+            else:
+                # Success!
+                break
 
         # Decode the flux list and read the index-times list.
         flux_list = self._decode_flux(dat)
@@ -247,20 +264,33 @@ class Unit:
         index_list = index_list[1:]
 
         # Success: Return the requested full index-to-index revolutions.
-        return Ack.Okay, Flux(index_list, flux_list, self.sample_freq)
+        return Flux(index_list, flux_list, self.sample_freq)
 
 
     ## write_track:
-    ## Write the given data stream to the current track via Greaseweazle.
-    def write_track(self, dat):
-        self._send_cmd(struct.pack("<2BIB", Cmd.WriteFlux, 7, 0, 1))
-        self.ser.write(dat)
-        self.ser.read(1) # Sync with Greaseweazle
-        try:
-            self._send_cmd(struct.pack("2B", Cmd.GetFluxStatus, 2))
-        except CmdError as error:
-            return error.code
-        return Ack.Okay
+    ## Write the given flux stream to the current track via Greaseweazle.
+    def write_track(self, flux_list, nr_retries=5):
+
+        # Create encoded data stream.
+        dat = self._encode_flux(flux_list)
+        
+        retry = 0
+        while True:
+            try:
+                # Write the flux stream to the track via Greaseweazle.
+                self._send_cmd(struct.pack("<2BIB", Cmd.WriteFlux, 7, 0, 1))
+                self.ser.write(dat)
+                self.ser.read(1) # Sync with Greaseweazle
+                self._send_cmd(struct.pack("2B", Cmd.GetFluxStatus, 2))
+            except CmdError as error:
+                # An error occurred. We may retry on transient underflows.
+                if error.code == Ack.FluxUnderflow and retry < nr_retries:
+                    retry += 1
+                else:
+                    raise error
+            else:
+                # Success!
+                break
 
 
     ##

+ 3 - 29
scripts/gw.py

@@ -35,22 +35,9 @@ def read_to_image(usb, args):
 
     for cyl in range(args.scyl, args.ecyl+1):
         for side in range(0, args.nr_sides):
-
             print("\rReading Track %u.%u..." % (cyl, side), end="")
             usb.seek(cyl, side)
-
-            # Physically read the track.
-            for retry in range(1, 5):
-                ack, flux = usb.read_track(args.revs)
-                if ack == USB.Ack.Okay:
-                    break
-                elif ack == USB.Ack.FluxOverflow and retry < 5:
-                    print("Retry #%u..." % (retry))
-                else:
-                    raise CmdError(ack)
-                
-            # Stash the data for later writeout to the image file.
-            image.append_track(flux)
+            image.append_track(usb.read_track(args.revs))
 
     print()
 
@@ -66,12 +53,7 @@ def write_from_image(usb, args):
     if args.adjust_speed:
         # @drive_ticks is the time in Gresaeweazle ticks between index pulses.
         # We will adjust the flux intervals per track to allow for this.
-        for retry in range(1, 5):
-            ack, flux = usb.read_track(2)
-            if ack == USB.Ack.Okay:
-                break
-            elif ack != USB.Ack.FluxOverflow or retry >= 5:
-                raise CmdError(ack)
+        flux = usb.read_track(2)
         drive_ticks = (flux.index_list[0] + flux.index_list[1]) / 2
         del flux
 
@@ -110,15 +92,7 @@ def write_from_image(usb, args):
                 flux_list.append(val)
 
             # Encode the flux times for Greaseweazle, and write them out.
-            enc_flux = usb.encode_flux(flux_list)
-            for retry in range(1, 5):
-                ack = usb.write_track(enc_flux)
-                if ack == USB.Ack.Okay:
-                    break
-                elif ack == USB.Ack.FluxUnderflow and retry < 5:
-                    print("Retry #%u..." % (retry))
-                else:
-                    raise CmdError(ack)
+            usb.write_track(flux_list)
 
     print()