192 Commits

Author SHA1 Message Date
Michael Ossmann
219abf7a4c Merge pull request #1180 from martinling/fix-transfer-locking
Improve transfer locking
2022-09-28 05:06:07 -04:00
Martin Ling
f7c219e30f Merge all_finished_lock with transfer_lock. 2022-09-26 14:01:16 +01:00
Martin Ling
367ce3d7b3 Hold transfer lock during initial submissions in prepare_transfers. 2022-09-26 14:01:15 +01:00
Martin Ling
559a45bd6b Extend scope of transfer_lock in callback. 2022-09-26 13:42:22 +01:00
Michael Ossmann
06b9d7bee0 Clean up source code copyright notices. 2022-09-23 14:46:52 -04:00
Martin Ling
2e73a4f2db If TX callback sets valid_length to 0, treat as end of data. 2022-09-23 12:46:49 +01:00
Martin Ling
0becbc6b4a Indicate success or failure to flush callback. 2022-09-23 05:19:29 -04:00
Martin Ling
4810d1f992 Fold transfer_finished function into libusb transfer callback. 2022-09-23 05:19:29 -04:00
Martin Ling
1484b78c05 Expand lock scope in libusb transfer callback.
This is required since cancel_transfers will also cancel the flush.
2022-09-23 05:19:29 -04:00
Martin Ling
770416f122 Cancel flush transfer if shutting down. 2022-09-23 05:19:29 -04:00
Martin Ling
14093fe73b Provide a callback for completion of a TX transfer. 2022-09-23 05:19:29 -04:00
Martin Ling
b872647e97 Provide a callback for TX flush, rather than a wait function. 2022-09-23 05:19:29 -04:00
Martin Ling
e53b9d5717 Fix hang in TX when a libusb error occurs.
Where our callback is called with a status other than COMPLETED,
something abnormal has happened and we no longer want to either
submit further transfers or await a flush. So clear the streaming
and flush flags, and proceed to transfer_finished.

Do the same in the case where libusb_submit_transfer fails when
called to submit the flush transfer.
2022-09-20 02:07:21 +01:00
Martin Ling
6ab17209d7 Disable flush when cancelling transfers. 2022-09-16 15:55:20 +01:00
Martin Ling
55fdddd81e Merge remote-tracking branch 'origin/master' into tx-transfer-sizing 2022-09-15 15:32:20 +01:00
Martin Ling
1b166a5b05 Pad the last data in a transmission to the next 512 byte boundary. 2022-09-15 15:27:53 +01:00
Martin Ling
69823397b1 Submit flush transfer as soon as end of data is reached. 2022-09-15 15:12:41 +01:00
Martin Ling
22846b5682 Make libhackrf honour the valid_length set by TX callback. 2022-09-14 15:48:34 +01:00
Michael Ossmann
9329c5e44e Detect hardware platform at run-time.
Firmware now detects the hardware it is running on at startup and
refuses to run if it is compiled for the wrong platform. The board ID
returned by firmware to the host is now derived from run-time detection
rather than a compile-time value. A separate method to retrieve
compile-time supported platform is added.

On HackRF One, pin straps are checked to determine hardware revision.
This is informational to aid troubleshooting and does not affect any
function.
2022-09-14 07:08:47 -04:00
Michael Ossmann
fdfe310f9a Merge pull request #1139 from martinling/tx-flush
Support flushing the device TX buffer before ending transmission
2022-09-14 05:45:40 -04:00
Michael Ossmann
70a04855ac libhackrf: add transfer buffer size access calls
Applications may need to learn the size of the USB transfer buffer
queue, for example to determine how many bytes will be preloaded with
calls to the TX callback.
2022-09-09 16:16:24 -04:00
Martin Ling
d556f0abab Add API to support flushing the device buffer when TX finishes. 2022-08-24 23:48:22 +01:00
Martin Ling
9d2e163a2d Call TX callback to fill transfers before initial submission. 2022-08-23 13:21:43 +01:00
Martin Ling
8bd8dedddc Use an early return to reduce indentation in prepare_transfers. 2022-08-23 13:03:53 +01:00
Martin Ling
5881b3b6a1 Add defines for TX and RX endpoint addresses. 2022-08-23 12:24:00 +01:00
Martin Ling
ba148ee047 Add a simpler way to check CLKIN status. 2022-08-05 09:37:38 +01:00
Martin Ling
c3fdf402d7 Reformat all code to new clang-format standard. 2022-08-03 23:46:44 +01:00
Martin Ling
0724bd36eb Lock the whole code block that touches active transfer count.
I believe this was safe before, because this code is only called from
the transfer thread, and the condition being protected is just whether
the count is zero, not the actual value of the count.

However, this isn't performance critical and it's a lot easier to
reason about the code if we just hold the lock for this whole section.
2022-07-04 18:00:07 +01:00
Martin Ling
743b2c76e2 Replace per-transfer flags with a count of active transfers.
This simplifies the code required to wait for cancellations to complete.
The condition variable now reflects whether `active_transfers == 0`, and
the associated lock must be held to decrement that count to zero.
2022-06-15 00:48:47 +01:00
Martin Ling
f046ed24a3 Remove duplicate stop command in hackrf_close(). 2022-03-18 10:59:34 +00:00
Martin Ling
b109a31fd3 Merge hackrf_stop_tx_cmd and hackrf_start_tx_cmd.
These both do the same thing: set transceiver mode to OFF.
2022-03-18 10:56:58 +00:00
Martin Ling
958c742189 Remove delays from hackrf_stop_rx_cmd and hackrf_stop_tx_cmd.
These were added in #805, as a workaround to prevent their parent
functions from returning before transfer cancellations had completed.
This has since been fixed properly in #1029.
2022-03-18 10:42:40 +00:00
Martin Ling
503cd3316c Remove request_exit() function.
This just set the do_exit flag, and was now only called in one place.
2022-03-18 02:20:34 +00:00
Martin Ling
c4789df44c Set streaming flag in prepare_transfers().
This simplifies prepare_setup_transfers(), which was just setting
the flag if prepare_transfers() returned success, and passing on
its return value.
2022-03-18 02:20:34 +00:00
Martin Ling
5afd31e21c Set streaming flag in prepare_setup_transfers().
Avoids conditionally duplicating this across three other places.
2022-03-18 02:20:34 +00:00
Martin Ling
960d8015a4 Clear streaming flag in cancel_transfers().
Moving this into cancel_transfers() avoids duplicating it in the two
stop functions.
2022-03-18 02:20:34 +00:00
Martin Ling
c74c742391 Simplify hackrf_libusb_transfer_callback.
There are now only two possible outcomes to this function: either we
successfully resubmitted a transfer, or the transfer is finished and we
end up calling transfer_finished().

So we can go ahead and simplify it accordingly.
2022-03-18 02:20:34 +00:00
Martin Ling
54e00de167 Clear streaming flag in transfer_finished().
Since we always do these together, move it into the function.
2022-03-18 02:20:34 +00:00
Martin Ling
6bd9cb0553 Clear streaming flag if a transfer was cancelled.
If a transfer was cancelled, we are on our way to shutdown.

If hackrf_stop_tx() or hackrf_stop_rx() were called, they will already
have cleared this flag, but it is not cleared in hackrf_close(), and
for consistency with other paths it makes sense to clear it here.
2022-03-18 02:20:34 +00:00
Martin Ling
125bf9f7bb Don't call callback or submit new transfers once streaming stops.
This stops the RX callback from being called again with further data
once it has returned nonzero, or after a transfer had an error status.
2022-03-18 02:20:34 +00:00
Martin Ling
6720e56fc0 Clear streaming flag if we didn't resubmit a transfer.
If result < 0 here, libusb_submit_transfer returned an error, so we
need to shut down.

If !resubmit, then cancel_transfers() was already called by one of the
stop or close functions, so streaming is already false.
2022-03-18 02:20:34 +00:00
Martin Ling
9e1cb5c003 Don't exit transfer thread if an error occurs.
In the case of a libusb error, we still need the transfer thread
running, in order to handle outstanding cancellations and to signal the
condition variable when that is done.
2022-03-18 01:57:40 +00:00
Mathieu Peyréga
a8a6618728 fix regression in 4c9fcf86651232c2104b57510a0ac86cf86123e4 2022-03-17 21:06:21 +01:00
Yan
790de7f47b Cleaner fast exit
Interrupt the event handling thread instead of waiting for timeout.
2022-03-16 11:13:00 +00:00
Yan
7ff92b3b05 Ensure fast exit
transfer_threadproc has a timeout of half a second, so
when kill_transfer_thread tries to pthread_join, it often
has to wait until the timeout kicks in.

With this fix, we ensure that a final request is made after
request_exit has been called, so that transfer_threadproc can exit its
loop in a fast and clean manner.
2022-03-15 12:43:45 +00:00
Martin Ling
779483b9bd Make M0 state retrieval endian-safe. 2022-02-13 17:53:34 +00:00
Martin Ling
5abc39c53a 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.
2022-02-13 16:46:12 +00:00
Martin Ling
fd073e391f Add USB vendor request to read M0 state, and host support for doing so.
This adds a `hackrf_debug [-S|--state]` option, and the necessary
plumbing to libhackrf and the M4 firmware to support it.

The USB API and libhackrf versions are bumped to reflect the changes.
2022-02-13 16:46:12 +00:00
Martin Ling
4c9fcf8665 After cancelling transfers, wait for all handling to complete.
Calling libusb_cancel_transfer only starts the cancellation of a
transfer. The process is not complete until the transfer callback
has been called with status LIBUSB_TRANSFER_CANCELLED.

If hackrf_start_rx() is called soon after hackrf_stop_rx(),
prepare_transfers() may be called before the previous cancellations
are completed, resulting in a LIBUSB_ERROR_BUSY when a transfer is
reused with libusb_submit_transfer().

To prevent this happening, we keep track of which transfers have
finished (either by completion, or cancellation), and make
cancel_transfers() wait until all transfers are finished.

This is implemented using a pthread condition variable which is
signalled from the transfer thread.
2022-02-03 06:44:20 +00:00
Martin Ling
837b5ee9c8 Use a lock to prevent transfers being restarted during cancellation.
Fixes bug #916.

Previously, there was a race which could lead to a transfer being left
active after cancel_transfers() completed. This would then cause the
next prepare_transfers() call to fail, because libusb_submit_transfer()
would return an error due to the transfer already being in use.

The sequence of events that could cause this was:

1. Main thread calls hackrf_stop_rx(), which calls cancel_transfers(),
   which iterates through the 4 transfers in use and cancels them one
   by one with libusb_cancel_transfer().

2. During this time, a transfer is completed. The transfer thread calls
   hackrf_libusb_transfer_callback(), which handles the data and then
   calls libusb_submit_transfer() to resubmit that transfer.

3. Now, cancel_transfers() and hackrf_stop_rx() are completed but one
   transfer is still active.

4. The next hackrf_start_rx() call fails, because prepare_transfers()
   tries to submit a transfer which is already in use.

To fix this, we add a lock which must be held to either cancel transfers
or restart them. This ensures that only one of these actions can happen
for a given transfer; it's no longer possible for a transfer to be
cancelled and then immediately restarted.
2022-02-03 06:44:19 +00:00