Explorar el Código

ReadFlux: Allow max_index_post_ticks to be specified by the host.
Also: Improve USB protocol docs.

Keir Fraser hace 4 años
padre
commit
2b78b953b7
Se han modificado 2 ficheros con 28 adiciones y 15 borrados
  1. 16 7
      inc/cdc_acm_protocol.h
  2. 12 8
      src/floppy.c

+ 16 - 7
inc/cdc_acm_protocol.h

@@ -12,15 +12,18 @@
 
 /*
  * GREASEWEAZLE COMMAND SET
+ * 
+ * NOTE: Commands cannot be pipelined. Do not issue a new command until the
+ * previous command is completed with all expected bytes received by the host.
  */
 
 /* CMD_GET_INFO, length=3, idx. Returns 32 bytes after ACK. */
 #define CMD_GET_INFO        0
 /* [BOOTLOADER] CMD_UPDATE, length=6, <update_len>. 
- * Host follows with <update_len> bytes.
+ * Host follows after a successful ACK response with <update_len> bytes.
  * Bootloader finally returns a status byte, 0 on success. */
 /* [MAIN FIRMWARE] CMD_UPDATE, length=10, <update_len>, 0xdeafbee3.
- * Host follows with <update_len> bytes.
+ * Host follows after a successful ACK response with <update_len> bytes.
  * Main firmware finally returns a status byte, 0 on success. */
 #define CMD_UPDATE          1
 /* CMD_SEEK, length=3, cyl#. Seek to cyl# on selected drive. */
@@ -33,15 +36,17 @@
 #define CMD_GET_PARAMS      5
 /* CMD_MOTOR, length=4, drive#, on/off. Turn on/off a drive motor. */
 #define CMD_MOTOR           6
-/* CMD_READ_FLUX, length=2-8. Argument is gw_read_flux.
- * Returns flux readings until EOStream. */
+/* CMD_READ_FLUX, length=8-12. Argument is gw_read_flux; optional fields
+ * may be omitted. Returns flux readings terminating with EOStream (NUL). */
 #define CMD_READ_FLUX       7
-/* CMD_WRITE_FLUX, length=2-4. Argument is gw_write_flux.
- * Host follows with flux readings until EOStream. */
+/* CMD_WRITE_FLUX, length=4. Argument is gw_write_flux.
+ * Host follows the ACK with flux values terminating with EOStream (NUL).
+ * Device finally returns a status byte, 0 on success. */
 #define CMD_WRITE_FLUX      8
 /* CMD_GET_FLUX_STATUS, length=2. Last read/write status returned in ACK. */
 #define CMD_GET_FLUX_STATUS 9
-/* CMD_SWITCH_FW_MODE, length=3, <mode> */
+/* CMD_SWITCH_FW_MODE, length=3, <mode>. No response on success: The device 
+ * resets into the requested mode, and the USB connection also resets. */
 #define CMD_SWITCH_FW_MODE 11
 /* CMD_SELECT, length=3, drive#. Select drive# as current unit. */
 #define CMD_SELECT         12
@@ -152,10 +157,14 @@ struct packed gw_bw_stats {
 
 /* CMD_READ_FLUX */
 struct packed gw_read_flux {
+    /** MANDATORY FIELDS: **/
     /* Maximum ticks to read for (or 0, for no limit). */
     uint32_t ticks;
     /* Maximum index pulses to read (or 0, for no limit). */
     uint16_t max_index;
+    /** OPTIONAL FIELDS: **/
+    /* Linger time, in ticks, to continue reading after @max_index pulses. */
+    uint32_t max_index_linger; /* default: 500 microseconds */
 };
 
 /* CMD_WRITE_FLUX */

+ 12 - 8
src/floppy.c

@@ -326,6 +326,7 @@ static void floppy_end_command(void *ack, unsigned int ack_len)
 static struct {
     unsigned int nr_index;
     unsigned int max_index;
+    uint32_t max_index_linger;
     time_t deadline;
 } read;
 
@@ -437,6 +438,7 @@ static uint8_t floppy_read_prep(const struct gw_read_flux *rf)
     read.max_index = rf->max_index ?: INT_MAX;
     read.deadline = flux_op.start;
     read.deadline += rf->ticks ? time_from_samples(rf->ticks) : INT_MAX;
+    read.max_index_linger = time_from_samples(rf->max_index_linger);
 
     return ACK_OKAY;
 }
@@ -477,17 +479,18 @@ static void floppy_read(void)
 
         } else if (read.nr_index >= read.max_index) {
 
-            /* Read all requested indexes. Allow for a short tail of data. */
-            time_t deadline = time_now() + time_us(500);
+            /* Index limit is reached: Now linger for the specified time. */
+            time_t deadline = time_now() + read.max_index_linger;
             if (time_diff(deadline, read.deadline) > 0)
                 read.deadline = deadline;
+            /* Disable max_index check: It's now become a linger deadline. */
             read.max_index = INT_MAX;
 
         }
 
         else if (time_since(read.deadline) >= 0) {
 
-            /* Read all requested data. */
+            /* Deadline is reached: End the read now. */
             floppy_flux_end();
             floppy_state = ST_read_flux_drain;
 
@@ -1164,17 +1167,18 @@ static void process_command(void)
         goto out;
     }
     case CMD_READ_FLUX: {
-        struct gw_read_flux rf;
-        if (len != (2 + sizeof(rf)))
+        struct gw_read_flux rf = {
+            .max_index_linger = sample_us(500)
+        };
+        if ((len < (2 + offsetof(struct gw_read_flux, max_index_linger)))
+            || (len > (2 + sizeof(rf))))
             goto bad_command;
         memcpy(&rf, &u_buf[2], len-2);
         u_buf[1] = floppy_read_prep(&rf);
         goto out;
     }
     case CMD_WRITE_FLUX: {
-        struct gw_write_flux wf = {
-            .cue_at_index = 1,
-            .terminate_at_index = 0 };
+        struct gw_write_flux wf;
         if (len != (2 + sizeof(wf)))
             goto bad_command;
         memcpy(&wf, &u_buf[2], len-2);