Provide a callback for TX flush, rather than a wait function.

This commit is contained in:
Martin Ling
2022-09-20 13:26:05 +01:00
committed by Michael Ossmann
parent c0ba843085
commit b872647e97
3 changed files with 47 additions and 41 deletions

View File

@ -499,7 +499,6 @@ int tx_callback(hackrf_transfer* transfer)
/* If the last data was already buffered, stop. */ /* If the last data was already buffered, stop. */
if (tx_complete) { if (tx_complete) {
stop_main_loop();
return -1; return -1;
} }
@ -558,6 +557,11 @@ int tx_callback(hackrf_transfer* transfer)
return 0; return 0;
} }
static void flush_callback(void* flush_ctx)
{
stop_main_loop();
}
static int update_stats(hackrf_device* device, hackrf_m0_state* state, stats_t* stats) static int update_stats(hackrf_device* device, hackrf_m0_state* state, stats_t* stats)
{ {
int result = hackrf_get_m0_state(device, state); int result = hackrf_get_m0_state(device, state);
@ -1252,7 +1256,7 @@ int main(int argc, char** argv)
preload_bytes = hackrf_get_transfer_queue_depth(device) * preload_bytes = hackrf_get_transfer_queue_depth(device) *
hackrf_get_transfer_buffer_size(device); hackrf_get_transfer_buffer_size(device);
result = hackrf_set_txvga_gain(device, txvga_gain); result = hackrf_set_txvga_gain(device, txvga_gain);
result |= hackrf_enable_tx_flush(device, 1); result |= hackrf_enable_tx_flush(device, flush_callback, NULL);
result |= hackrf_start_tx(device, tx_callback, NULL); result |= hackrf_start_tx(device, tx_callback, NULL);
} }
@ -1281,7 +1285,7 @@ int main(int argc, char** argv)
.it_value = {.tv_sec = 1, .tv_usec = 0}}; .it_value = {.tv_sec = 1, .tv_usec = 0}};
setitimer(ITIMER_REAL, &interval_timer, NULL); setitimer(ITIMER_REAL, &interval_timer, NULL);
#endif #endif
while ((hackrf_is_streaming(device) == HACKRF_TRUE) && (do_exit == false)) { while (!do_exit) {
uint64_t byte_count_now; uint64_t byte_count_now;
struct timeval time_now; struct timeval time_now;
float time_difference, rate; float time_difference, rate;
@ -1406,11 +1410,6 @@ int main(int argc, char** argv)
interval_timer.it_value.tv_sec = 0; interval_timer.it_value.tv_sec = 0;
setitimer(ITIMER_REAL, &interval_timer, NULL); setitimer(ITIMER_REAL, &interval_timer, NULL);
#endif #endif
if ((transmit || signalsource) && !interrupted) {
// Wait for TX to finish.
hackrf_await_tx_flush(device);
}
result = hackrf_is_streaming(device); result = hackrf_is_streaming(device);
if (do_exit) { if (do_exit) {
fprintf(stderr, "\nExiting...\n"); fprintf(stderr, "\nExiting...\n");

View File

@ -147,6 +147,8 @@ struct hackrf_device {
pthread_mutex_t all_finished_lock; /* used to protect all_finished */ pthread_mutex_t all_finished_lock; /* used to protect all_finished */
bool flush; bool flush;
struct libusb_transfer* flush_transfer; struct libusb_transfer* flush_transfer;
hackrf_flush_cb_fn flush_callback;
void* flush_ctx;
}; };
typedef struct { typedef struct {
@ -724,6 +726,8 @@ static int hackrf_open_setup(libusb_device_handle* usb_device, hackrf_device** d
lib_device->active_transfers = 0; lib_device->active_transfers = 0;
lib_device->flush = false; lib_device->flush = false;
lib_device->flush_transfer = NULL; lib_device->flush_transfer = NULL;
lib_device->flush_callback = NULL;
lib_device->flush_ctx = NULL;
result = pthread_mutex_init(&lib_device->transfer_lock, NULL); result = pthread_mutex_init(&lib_device->transfer_lock, NULL);
if (result != 0) { if (result != 0) {
@ -1788,6 +1792,8 @@ static void LIBUSB_CALL hackrf_libusb_flush_callback(struct libusb_transfer* usb
device->active_transfers = 0; device->active_transfers = 0;
pthread_cond_broadcast(&device->all_finished_cv); pthread_cond_broadcast(&device->all_finished_cv);
pthread_mutex_unlock(&device->all_finished_lock); pthread_mutex_unlock(&device->all_finished_lock);
if (device->flush_callback)
device->flush_callback(device->flush_ctx);
} }
static void LIBUSB_CALL static void LIBUSB_CALL
@ -2004,9 +2010,14 @@ int ADDCALL hackrf_start_tx(
return result; return result;
} }
int ADDCALL hackrf_enable_tx_flush(hackrf_device* device, int enable) ADDAPI int ADDCALL hackrf_enable_tx_flush(
hackrf_device* device,
hackrf_flush_cb_fn callback,
void* flush_ctx)
{ {
if (enable) { device->flush_callback = callback;
device->flush_ctx = flush_ctx;
if (device->flush_transfer) { if (device->flush_transfer) {
return HACKRF_SUCCESS; return HACKRF_SUCCESS;
} }
@ -2026,23 +2037,16 @@ int ADDCALL hackrf_enable_tx_flush(hackrf_device* device, int enable)
0); 0);
device->flush_transfer->flags = LIBUSB_TRANSFER_FREE_BUFFER; device->flush_transfer->flags = LIBUSB_TRANSFER_FREE_BUFFER;
} else {
libusb_free_transfer(device->flush_transfer);
device->flush_transfer = NULL;
}
return HACKRF_SUCCESS; return HACKRF_SUCCESS;
} }
int ADDCALL hackrf_await_tx_flush(hackrf_device* device) ADDAPI int ADDCALL hackrf_disable_tx_flush(hackrf_device* device)
{ {
// Wait for the transfer thread to signal that all transfers libusb_free_transfer(device->flush_transfer);
// have finished. device->flush_transfer = NULL;
pthread_mutex_lock(&device->all_finished_lock); device->flush_callback = NULL;
while (device->active_transfers > 0) { device->flush_ctx = NULL;
pthread_cond_wait(&device->all_finished_cv, &device->all_finished_lock);
}
pthread_mutex_unlock(&device->all_finished_lock);
return HACKRF_SUCCESS; return HACKRF_SUCCESS;
} }

View File

@ -228,6 +228,7 @@ struct hackrf_device_list {
typedef struct hackrf_device_list hackrf_device_list_t; typedef struct hackrf_device_list hackrf_device_list_t;
typedef int (*hackrf_sample_block_cb_fn)(hackrf_transfer* transfer); typedef int (*hackrf_sample_block_cb_fn)(hackrf_transfer* transfer);
typedef void (*hackrf_flush_cb_fn)(void* flush_ctx);
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -270,8 +271,10 @@ extern ADDAPI int ADDCALL hackrf_start_tx(
hackrf_sample_block_cb_fn callback, hackrf_sample_block_cb_fn callback,
void* tx_ctx); void* tx_ctx);
extern ADDAPI int ADDCALL hackrf_enable_tx_flush(hackrf_device* device, int enable); extern ADDAPI int ADDCALL hackrf_enable_tx_flush(
extern ADDAPI int ADDCALL hackrf_await_tx_flush(hackrf_device* device); hackrf_device* device,
hackrf_flush_cb_fn callback,
void* flush_ctx);
extern ADDAPI int ADDCALL hackrf_stop_tx(hackrf_device* device); extern ADDAPI int ADDCALL hackrf_stop_tx(hackrf_device* device);