ReadFlux: Allow max_index_post_ticks to be specified by the host.

Also: Improve USB protocol docs.
This commit is contained in:
Keir Fraser
2021-02-22 15:17:52 +00:00
parent dd4864c216
commit 2b78b953b7
2 changed files with 28 additions and 15 deletions

View File

@@ -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 */

View File

@@ -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);