Don't send 16K of zeroes to the M0 at TX startup.
by Martin Ling 3 years 10 months
Don't send 16K of zeroes to the M0 at TX startup.

The M4 previously buffered 16K of zeroes for the M0 to transmit, whilst
waiting for the first USB bulk transfer from the host to complete. The
first bulk transfer was placed in the second 16K buffer.

This avoided the M0 transmitting uninitialised data, but was not a
reliable solution, and delayed the transmission of the first
host-supplied samples.

Now that the M0 is placed in TX_START mode, this trick is no longer
necessary, because the M0 can automatically send zeroes until the first
bulk transfer is completed.

As such, the first bulk transfer now goes to the first 16K buffer.
Once the M4 byte count is increased by the bulk transfer completion
callback, the M0 will start transmitting the samples immediately.
68688e0e
Add an M0 TX_START mode, in which zeroes are sent ...
by Martin Ling 3 years 10 months
Add an M0 TX_START mode, in which zeroes are sent until data is ready.

In TX_START mode, a lack of data to send is not treated as a shortfall.
Zeroes are written to SGPIO, but no shortfall is recorded in the stats.
Using this mode helps avoid spurious shortfalls at startup.

As soon as there is data to transmit, the M0 switches to TX_RUN mode.

This change adds five cycles to the normal TX path, in order to check
for TX_START mode before sending data, and to switch to TX_RUN in that
case.

It also adds two cycles to the TX shortfall path, to check for TX_START
mode and skip shortfall processing in that mode.

Note the allocation of r3 to store the mode setting, such that this
value is still available after the tx_zeros routine.
00b5ed7d
Add USB requests and host support to set TX/RX sho...
by Martin Ling 3 years 10 months
Add USB requests and host support to set TX/RX shortfall limits.

This adds `-T` and `-R` options to `hackrf_debug`, which set the TX
underrun and RX overrun limits in bytes.
5abc39c5
hackrf_debug: allow parse_int() to handle 32-bit p...
by Martin Ling 3 years 10 months
hackrf_debug: allow parse_int() to handle 32-bit parameters.
2f79c03b
Add a shortfall length limit.
by Martin Ling 3 years 10 months
Add a shortfall length limit.

This limit allows implementing a timeout: if a TX underrun or RX overrun
continues for the specified number of bytes, the M0 will revert to idle.

A setting of zero disables the limit.

This change adds 5 cycles to the TX & RX shortfall paths, to check if a
limit is set and to check the shortfall length against the limit.
f0bc6eda
Keep track of longest shortfall.
by Martin Ling 3 years 10 months
Keep track of longest shortfall.

This adds six cycles to the TX and RX shortfall paths.
2c86f493
Keep count of number of shortfalls.
by Martin Ling 3 years 10 months
Keep count of number of shortfalls.

To enable this, we keep a count of the current shortfall length. Each
time an SGPIO read/write cannot be completed due to a shortfall, we
increase this length. Each time an SGPIO read/write is completed
successfully, we reset the shortfall length to zero.

When a shortfall occurs and the existing shortfall length is zero, this
indicates a new shortfall, and the shortfall count is incremented.

This change adds one cycle to the normal RX & TX paths, to zero the
shortfall count. To enable this to be done in a single cycle, we keep a
zero handy in a high register.

The extra accounting adds 10 cycles to the TX and RX shortfall paths,
plus an additional 3 cycles to the RX shortfall path since there are
now two branches involved: one to the shortfall handler, and another
back to the main loop.
a7bd1e3e
Move resetting of byte counts to the M0.
by Martin Ling 3 years 10 months
Move resetting of byte counts to the M0.

Previously, these counts were zeroed by the M4 when leaving the OFF
transceiver mode. Instead, do this on the M0 at the point where the M0
leaves IDLE mode.

This avoids a potential race in which the M4 zeroes the M0 count after
the M0 has already started incrementing it.
0f3069ee
Set M0 mode to IDLE when transceiver mode is OFF.
by Martin Ling 3 years 10 months
Set M0 mode to IDLE when transceiver mode is OFF.

At this point, streaming has been stopped, so there will be no further
SGPIO interrupts. However, the M0 will still be spinning on the interrupt
flag, waiting to proceed.

To ensure that the M0 actually reaches its idle loop, we set the SGPIO
interrupt flag once. The M0 will then finish spinning on the flag, clear
the flag, see the new mode setting, and jump to the idle loop.
3fd3c778
Add an idle mode for the M0.
by Martin Ling 3 years 10 months
Add an idle mode for the M0.

In the idle mode, the M0 simply waits for a different mode to be set.
No SGPIO access is done.

One extra cycle is added to both TX code paths, to check whether the
M0 should return to the idle loop based on the mode setting. The RX
paths are unaffected as the branch to RX is handled first.
32c725dd
Report a bug