happycube / cxadc-linux3

CX2388x direct ADC capture driver, updated for Linux 3.x+ and 64-bit
81 stars 18 forks source link

Make reading MO_VBI_GPCNT more robust #52

Closed rianhunter closed 7 months ago

rianhunter commented 7 months ago

The value of MO_VBI_GPCNT doesn't necessarily reflect which pages from the CX card have made it to main memory. I.e. it's possible for MO_VBI_GPCNT to return 1 yet the first page is not yet in main memory.

Previously this was handled by only assuming MO_VBI_GPCNT - 1 have been written. The -1 here serves as a heuristic that tends to works in most cases but I've noticed that in some rare cases the GPCNT can be out of sync by 2 pages. The other side effect is that we start the capture from 1 page behind the current page which may not be desirable either.

To address this we only trust the value of MO_VBI_GPCNT after an interrupt has occurred. We round the value down to the last value that we know should have caused the interrupt. Note that if the interrupt is delayed by an excessively long time then we may read a MO_VBI_GPCNT value that corresponds to a subsequent interrupt that hasn't occured yet. In practice the interrupt occurs every 0x200 pages, which ends up being 0x200 * 4096 / 40000000 = ~52ms and latency that high should almost never occur in practice.

An alternative here is to not read MO_VBI_GPCNT at all and to instead just count interrupts. This is what the official cx88 Linux driver does. I opted not to take that route to avoid excessive churn and I'm not sure if interrupts queue. If interrupts indeed do queue, then that may be an even more robust approach.