mirror of
https://github.com/keirf/greaseweazle-firmware.git
synced 2025-10-31 11:06:44 -07:00
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.
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
/*
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
71
src/floppy.c
71
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;
|
||||
|
||||
Reference in New Issue
Block a user