Forráskód Böngészése

usb: Send periodic noflux opcodes during long periods of no flux.
This new no-flux opcode replaces the long-flux opcode:
long-flux = no-flux + regular-flux
Also rearrange the code a bit to avoid repetition.

Keir Fraser 4 éve
szülő
commit
e7062e3ad8
3 módosított fájl, 73 hozzáadás és 64 törlés
  1. 2 2
      inc/cdc_acm_protocol.h
  2. 32 30
      scripts/greaseweazle/usb.py
  3. 39 32
      src/floppy.c

+ 2 - 2
inc/cdc_acm_protocol.h

@@ -98,8 +98,8 @@
 /*
  * Flux stream opcodes. Preceded by 0xFF byte.
  */
-#define FLUXOP_LONGFLUX   1
-#define FLUXOP_INDEX      2
+#define FLUXOP_INDEX      1
+#define FLUXOP_NOFLUX     2
 
 
 /*

+ 32 - 30
scripts/greaseweazle/usb.py

@@ -111,8 +111,8 @@ class BusType:
 
 ## Flux read stream opcodes, preceded by 0xFF byte
 class FluxOp:
-    LongFlux        = 1
-    Index           = 2
+    Index           = 1
+    NoFlux          = 2
 
 
 ## CmdError: Encapsulates a command acknowledgement.
@@ -263,38 +263,37 @@ class Unit:
     def _decode_flux(self, dat):
         flux, index = [], []
         dat_i = iter(dat)
-        ticks_since_index = 0
+        ticks, ticks_since_index = 0, 0
+        def _read_28bit():
+            val =  (next(dat_i) & 254) >>  1
+            val += (next(dat_i) & 254) <<  6
+            val += (next(dat_i) & 254) << 13
+            val += (next(dat_i) & 254) << 20
+            return val
         try:
             while True:
                 i = next(dat_i)
-                if i < 250:
-                    flux.append(i)
-                    ticks_since_index += i
-                elif i == 255:
+                if i == 255:
                     opcode = next(dat_i)
-                    if opcode == FluxOp.LongFlux:
-                        val =  (next(dat_i) & 254) >>  1
-                        val += (next(dat_i) & 254) <<  6
-                        val += (next(dat_i) & 254) << 13
-                        val += (next(dat_i) & 254) << 20
-                        flux.append(val)
-                        ticks_since_index += val
-                    elif opcode == FluxOp.Index:
-                        val =  (next(dat_i) & 254) >>  1
-                        val += (next(dat_i) & 254) <<  6
-                        val += (next(dat_i) & 254) << 13
-                        val += (next(dat_i) & 254) << 20
-                        index.append(ticks_since_index + val)
+                    if opcode == FluxOp.Index:
+                        val = _read_28bit()
+                        index.append(ticks_since_index + ticks + val)
                         ticks_since_index = -val
-                        pass
+                    elif opcode == FluxOp.NoFlux:
+                        ticks += _read_28bit()
                     else:
                         raise error.Fatal("Bad opcode in flux stream (%d)"
                                           % opcode)
                 else:
-                    val = 250 + (i - 250) * 255
-                    val += next(dat_i) - 1
-                    flux.append(val)
-                    ticks_since_index += val
+                    if i < 250:
+                        val = i
+                    else:
+                        val = 250 + (i - 250) * 255
+                        val += next(dat_i) - 1
+                    ticks += val
+                    flux.append(ticks)
+                    ticks_since_index += ticks
+                    ticks = 0
         except StopIteration:
             pass
         error.check(flux[-1] == 0, "Missing terminator on flux read stream")
@@ -305,6 +304,11 @@ class Unit:
     ## Convert the given flux timings into an encoded data stream.
     def _encode_flux(self, flux):
         dat = bytearray()
+        def _write_28bit(x):
+            dat.append(1 | (x<<1) & 255)
+            dat.append(1 | (x>>6) & 255)
+            dat.append(1 | (x>>13) & 255)
+            dat.append(1 | (x>>20) & 255)
         for val in flux:
             if val == 0:
                 pass
@@ -317,11 +321,9 @@ class Unit:
                     dat.append(1 + (val-250) % 255)
                 else:
                     dat.append(255)
-                    dat.append(FluxOp.LongFlux)
-                    dat.append(1 | (val<<1) & 255)
-                    dat.append(1 | (val>>6) & 255)
-                    dat.append(1 | (val>>13) & 255)
-                    dat.append(1 | (val>>20) & 255)
+                    dat.append(FluxOp.NoFlux)
+                    _write_28bit(val - 249);
+                    dat.append(249)
         dat.append(0) # End of Stream
         return dat
 

+ 39 - 32
src/floppy.c

@@ -299,12 +299,20 @@ static struct {
     uint8_t packet[USB_HS_MPS];
 } rw;
 
+static always_inline void _write_28bit(uint32_t x)
+{
+    u_buf[U_MASK(u_prod++)] = 1 | (x << 1);
+    u_buf[U_MASK(u_prod++)] = 1 | (x >> 6);
+    u_buf[U_MASK(u_prod++)] = 1 | (x >> 13);
+    u_buf[U_MASK(u_prod++)] = 1 | (x >> 20);
+}
+
 static void rdata_encode_flux(void)
 {
     const uint16_t buf_mask = ARRAY_SIZE(dma.buf) - 1;
     uint16_t cons = dma.cons, prod;
     timcnt_t prev = dma.prev_sample, curr, next;
-    uint32_t ticks = rw.ticks_since_flux;
+    uint32_t ticks;
 
     ASSERT(rw.idx < rw.nr_idx);
 
@@ -317,14 +325,10 @@ static void rdata_encode_flux(void)
     if (rw.idx != index.count) {
         /* We have just passed the index mark: Record information about 
          * the just-completed revolution. */
-        int partial_flux = ticks + (timcnt_t)(index.rdata_cnt - prev);
-        ASSERT(partial_flux >= 0);
+        unsigned int partial_flux = (timcnt_t)(index.rdata_cnt - prev);
         u_buf[U_MASK(u_prod++)] = 0xff;
         u_buf[U_MASK(u_prod++)] = FLUXOP_INDEX;
-        u_buf[U_MASK(u_prod++)] = 1 | (partial_flux << 1);
-        u_buf[U_MASK(u_prod++)] = 1 | (partial_flux >> 6);
-        u_buf[U_MASK(u_prod++)] = 1 | (partial_flux >> 13);
-        u_buf[U_MASK(u_prod++)] = 1 | (partial_flux >> 20);
+        _write_28bit(partial_flux);
         rw.idx = index.count;
     }
 
@@ -336,7 +340,7 @@ static void rdata_encode_flux(void)
         curr = next - prev;
         prev = next;
 
-        ticks += curr;
+        ticks = curr;
 
         if (ticks == 0) {
             /* 0: Skip. */
@@ -350,36 +354,31 @@ static void rdata_encode_flux(void)
                 u_buf[U_MASK(u_prod++)] = 250 + high;
                 u_buf[U_MASK(u_prod++)] = 1 + ((ticks-250) % 255);
             } else {
-                /* 1525-(2^28-1): Six bytes */
+                /* 1525-(2^28-1): Seven bytes. */
                 u_buf[U_MASK(u_prod++)] = 0xff;
-                u_buf[U_MASK(u_prod++)] = FLUXOP_LONGFLUX;
-                u_buf[U_MASK(u_prod++)] = 1 | (ticks << 1);
-                u_buf[U_MASK(u_prod++)] = 1 | (ticks >> 6);
-                u_buf[U_MASK(u_prod++)] = 1 | (ticks >> 13);
-                u_buf[U_MASK(u_prod++)] = 1 | (ticks >> 20);
+                u_buf[U_MASK(u_prod++)] = FLUXOP_NOFLUX;
+                _write_28bit(ticks - 249);
+                u_buf[U_MASK(u_prod++)] = 249;
             }
         }
-
-        ticks = 0;
     }
 
     /* If it has been a long time since the last flux timing, transfer some of
-     * the accumulated time from the 16-bit timestamp into the 32-bit
-     * accumulator. This avoids 16-bit overflow and because, we take care to
-     * keep the 16-bit timestamp at least 200us behind, we cannot race the next
-     * flux timestamp. */
-    if (sizeof(timcnt_t) == sizeof(uint16_t)) {
-        curr = tim_rdata->cnt - prev;
-        if (unlikely(curr > sample_us(400))) {
-            prev += sample_us(200);
-            ticks += sample_us(200);
-        }
+     * the accumulated time to the host in a "long gap" sample. This avoids
+     * timing overflow and, because we take care to keep @prev well behind the
+     * sample clock, we cannot race the next flux timestamp. */
+    curr = tim_rdata->cnt - prev;
+    if (unlikely(curr > sample_us(400))) {
+        ticks = sample_us(200);
+        u_buf[U_MASK(u_prod++)] = 0xff;
+        u_buf[U_MASK(u_prod++)] = FLUXOP_NOFLUX;
+        _write_28bit(ticks);
+        prev += ticks;
     }
 
     /* Save our progress for next time. */
     dma.cons = cons;
     dma.prev_sample = prev;
-    rw.ticks_since_flux = ticks;
 }
 
 static uint8_t floppy_read_prep(const struct gw_read_flux *rf)
@@ -487,6 +486,16 @@ static void floppy_read(void)
  * WRITE PATH
  */
 
+static always_inline uint32_t _read_28bit(void)
+{
+    uint32_t x;
+    x  = (u_buf[U_MASK(u_cons++)]       ) >>  1;
+    x |= (u_buf[U_MASK(u_cons++)] & 0xfe) <<  6;
+    x |= (u_buf[U_MASK(u_cons++)] & 0xfe) << 13;
+    x |= (u_buf[U_MASK(u_cons++)] & 0xfe) << 20;
+    return x;
+}
+
 static unsigned int _wdata_decode_flux(timcnt_t *tbuf, unsigned int nr)
 {
     unsigned int todo = nr;
@@ -527,11 +536,9 @@ static unsigned int _wdata_decode_flux(timcnt_t *tbuf, unsigned int nr)
             /* 255: Six bytes */
             if ((uint32_t)(u_prod - u_cons) < 6)
                 goto out;
-            u_cons += 2; /* skip 255, 1 */
-            x  = (u_buf[U_MASK(u_cons++)]       ) >>  1;
-            x |= (u_buf[U_MASK(u_cons++)] & 0xfe) <<  6;
-            x |= (u_buf[U_MASK(u_cons++)] & 0xfe) << 13;
-            x |= (u_buf[U_MASK(u_cons++)] & 0xfe) << 20;
+            u_cons += 2; /* skip 255, FLUXOP_NOFLUX */
+            ticks += _read_28bit();
+            continue;
         }
 
         ticks += x;