fix: RTL-SDR bug fixes and accuracy improvements

This commit is contained in:
2026-07-03 10:36:41 +02:00
parent 108538f60c
commit daa17a325f
5 changed files with 201 additions and 47 deletions
+33
View File
@@ -1024,6 +1024,10 @@ namespace Drivers::USB::Xhci {
if (slotId == 0 || slotId > MAX_SLOTS || !g_devices[slotId].Active) return;
UsbDeviceInfo& dev = g_devices[slotId];
if (!dev.BulkInRing || dev.BulkInEpNum == 0) return;
// Already armed: priming again would put a second transfer on the ring
// for every pool buffer and desync the completion rotation (callbacks
// would be handed the wrong buffer). Callers must Stop first.
if (g_bulkInPoolCount[slotId] != 0) return;
if (numBuffers < 1) numBuffers = 1;
if (numBuffers > BULK_IN_POOL_MAX) numBuffers = BULK_IN_POOL_MAX;
@@ -1060,7 +1064,36 @@ namespace Drivers::USB::Xhci {
if (slotId == 0 || slotId > MAX_SLOTS) return;
// Disarm the rotation; any late completion now takes the (no-op for SDR)
// legacy path and is not re-armed. Buffers are retained for reuse.
bool wasArmed = g_bulkInPoolCount[slotId] != 0;
g_bulkInPoolCount[slotId] = 0;
if (!wasArmed) return;
// Flush the up-to-PoolCount TRBs still pending on the ring: Stop
// Endpoint, then Set TR Dequeue to the enqueue pointer. Without this a
// later Start would stack a fresh pool behind the stale TRBs and
// overflow the 32-entry transfer ring (16 stale + 16 new > 31 usable),
// wrapping the enqueue pointer onto still-pending TRBs.
UsbDeviceInfo& dev = g_devices[slotId];
if (!dev.Active || dev.BulkInEpNum == 0 || !dev.BulkInRing) return;
uint8_t dci = dev.BulkInEpNum * 2 + 1;
TRB stopTrb = {};
stopTrb.Control = (TRB_STOP_ENDPOINT << TRB_TYPE_SHIFT)
| ((uint32_t)slotId << 24)
| ((uint32_t)dci << 16);
SendCommand(stopTrb);
uint64_t newDeq = dev.BulkInRingPhys
+ (uint64_t)dev.BulkInRingEnqueue * sizeof(TRB);
if (dev.BulkInRingCCS) newDeq |= 1; // DCS bit
TRB deqTrb = {};
deqTrb.Parameter0 = (uint32_t)(newDeq & 0xFFFFFFFF);
deqTrb.Parameter1 = (uint32_t)(newDeq >> 32);
deqTrb.Control = (TRB_SET_TR_DEQUEUE << TRB_TYPE_SHIFT)
| ((uint32_t)slotId << 24)
| ((uint32_t)dci << 16);
SendCommand(deqTrb);
}
// -------------------------------------------------------------------------