diff --git a/firmware/common/hackrf_core.h b/firmware/common/hackrf_core.h index 912fa991..c3a47b69 100644 --- a/firmware/common/hackrf_core.h +++ b/firmware/common/hackrf_core.h @@ -256,7 +256,8 @@ typedef enum { TRANSCEIVER_MODE_RX = 1, TRANSCEIVER_MODE_TX = 2, TRANSCEIVER_MODE_SS = 3, - TRANSCEIVER_MODE_CPLD_UPDATE = 4 + TRANSCEIVER_MODE_CPLD_UPDATE = 4, + TRANSCEIVER_MODE_RX_SWEEP = 5, } transceiver_mode_t; typedef enum { diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index 364677ca..f468fc1d 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -252,46 +252,22 @@ int main(void) { } operacake_init(operacake_allow_gpio); - unsigned int phase = 0; - usb_bulk_buffer_offset = 0; - while(true) { - // Check whether we need to initiate a CPLD update - if (start_cpld_update) - cpld_update(); - - // Check whether we need to initiate sweep mode - if (start_sweep_mode) { - start_sweep_mode = false; + switch (transceiver_mode()) { + case TRANSCEIVER_MODE_RX: + rx_mode(); + break; + case TRANSCEIVER_MODE_TX: + tx_mode(); + break; + case TRANSCEIVER_MODE_RX_SWEEP: sweep_mode(); - } - - // Set up IN transfer of buffer 0. - if ( usb_bulk_buffer_offset >= 16384 - && phase == 1 - && transceiver_mode() != TRANSCEIVER_MODE_OFF) { - usb_transfer_schedule_block( - (transceiver_mode() == TRANSCEIVER_MODE_RX) - ? &usb_endpoint_bulk_in : &usb_endpoint_bulk_out, - &usb_bulk_buffer[0x0000], - 0x4000, - NULL, NULL - ); - phase = 0; - } - - // Set up IN transfer of buffer 1. - if ( usb_bulk_buffer_offset < 16384 - && phase == 0 - && transceiver_mode() != TRANSCEIVER_MODE_OFF) { - usb_transfer_schedule_block( - (transceiver_mode() == TRANSCEIVER_MODE_RX) - ? &usb_endpoint_bulk_in : &usb_endpoint_bulk_out, - &usb_bulk_buffer[0x4000], - 0x4000, - NULL, NULL - ); - phase = 1; + break; + case TRANSCEIVER_MODE_CPLD_UPDATE: + cpld_update(); + break; + default: + break; } } diff --git a/firmware/hackrf_usb/usb_api_cpld.c b/firmware/hackrf_usb/usb_api_cpld.c index fc5ab51f..e6fa3784 100644 --- a/firmware/hackrf_usb/usb_api_cpld.c +++ b/firmware/hackrf_usb/usb_api_cpld.c @@ -33,7 +33,6 @@ #include #include -volatile bool start_cpld_update = false; uint8_t cpld_xsvf_buffer[512]; volatile bool cpld_wait = false; diff --git a/firmware/hackrf_usb/usb_api_cpld.h b/firmware/hackrf_usb/usb_api_cpld.h index a097c6a8..5b82eca5 100644 --- a/firmware/hackrf_usb/usb_api_cpld.h +++ b/firmware/hackrf_usb/usb_api_cpld.h @@ -28,8 +28,6 @@ #include #include -extern volatile bool start_cpld_update; - void cpld_update(void); usb_request_status_t usb_vendor_request_cpld_checksum( diff --git a/firmware/hackrf_usb/usb_api_sweep.c b/firmware/hackrf_usb/usb_api_sweep.c index 5c9b5efa..a664c388 100644 --- a/firmware/hackrf_usb/usb_api_sweep.c +++ b/firmware/hackrf_usb/usb_api_sweep.c @@ -27,6 +27,7 @@ #include "usb_bulk_buffer.h" #include "tuning.h" #include "usb_endpoint.h" +#include "streaming.h" #define MIN(x,y) ((x)<(y)?(x):(y)) #define MAX(x,y) ((x)>(y)?(x):(y)) @@ -34,7 +35,6 @@ #define MAX_RANGES 10 #define THROWAWAY_BUFFERS 2 -volatile bool start_sweep_mode = false; static uint64_t sweep_freq; static uint16_t frequencies[MAX_RANGES * 2]; static unsigned char data[9 + MAX_RANGES * 2 * sizeof(frequencies[0])]; @@ -44,6 +44,7 @@ static uint32_t step_width = 0; static uint32_t offset = 0; static enum sweep_style style = LINEAR; +/* Do this before starting sweep mode with set_transceiver_mode(). */ usb_request_status_t usb_vendor_request_init_sweep( usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) { @@ -78,7 +79,6 @@ usb_request_status_t usb_vendor_request_init_sweep( } sweep_freq = (uint64_t)frequencies[0] * FREQ_GRANULARITY; set_freq(sweep_freq + offset); - start_sweep_mode = true; usb_transfer_schedule_ack(endpoint->in); } return USB_REQUEST_STATUS_OK; @@ -93,7 +93,9 @@ void sweep_mode(void) { uint8_t *buffer; bool transfer = false; - while(transceiver_mode() != TRANSCEIVER_MODE_OFF) { + baseband_streaming_enable(&sgpio_config); + + while (TRANSCEIVER_MODE_RX_SWEEP == transceiver_mode()) { // Set up IN transfer of buffer 0. if ( usb_bulk_buffer_offset >= 16384 && phase == 1) { transfer = true; diff --git a/firmware/hackrf_usb/usb_api_sweep.h b/firmware/hackrf_usb/usb_api_sweep.h index 20c27859..11ba4395 100644 --- a/firmware/hackrf_usb/usb_api_sweep.h +++ b/firmware/hackrf_usb/usb_api_sweep.h @@ -26,8 +26,6 @@ #include #include -extern volatile bool start_sweep_mode; - enum sweep_style { LINEAR = 0, INTERLEAVED = 1, diff --git a/firmware/hackrf_usb/usb_api_transceiver.c b/firmware/hackrf_usb/usb_api_transceiver.c index 90f50810..a113f2e9 100644 --- a/firmware/hackrf_usb/usb_api_transceiver.c +++ b/firmware/hackrf_usb/usb_api_transceiver.c @@ -36,8 +36,10 @@ #include #include +#include #include "usb_endpoint.h" +#include "usb_api_sweep.h" typedef struct { uint32_t freq_mhz; @@ -251,17 +253,22 @@ void set_transceiver_mode(const transceiver_mode_t new_transceiver_mode) { _transceiver_mode = new_transceiver_mode; - if( _transceiver_mode == TRANSCEIVER_MODE_RX ) { + switch (_transceiver_mode) { + case TRANSCEIVER_MODE_RX_SWEEP: + case TRANSCEIVER_MODE_RX: led_off(LED3); led_on(LED2); rf_path_set_direction(&rf_path, RF_PATH_DIRECTION_RX); usb_bulk_buffer_tx = false; - } else if (_transceiver_mode == TRANSCEIVER_MODE_TX) { + break; + case TRANSCEIVER_MODE_TX: led_off(LED2); led_on(LED3); rf_path_set_direction(&rf_path, RF_PATH_DIRECTION_TX); usb_bulk_buffer_tx = true; - } else { + break; + case TRANSCEIVER_MODE_OFF: + default: led_off(LED2); led_off(LED3); rf_path_set_direction(&rf_path, RF_PATH_DIRECTION_OFF); @@ -274,7 +281,7 @@ void set_transceiver_mode(const transceiver_mode_t new_transceiver_mode) { hw_sync_enable(_hw_sync_mode); - baseband_streaming_enable(&sgpio_config); + usb_bulk_buffer_offset = 0; } } @@ -287,11 +294,9 @@ usb_request_status_t usb_vendor_request_set_transceiver_mode( case TRANSCEIVER_MODE_OFF: case TRANSCEIVER_MODE_RX: case TRANSCEIVER_MODE_TX: - set_transceiver_mode(endpoint->setup.value); - usb_transfer_schedule_ack(endpoint->in); - return USB_REQUEST_STATUS_OK; + case TRANSCEIVER_MODE_RX_SWEEP: case TRANSCEIVER_MODE_CPLD_UPDATE: - start_cpld_update = true; + set_transceiver_mode(endpoint->setup.value); usb_transfer_schedule_ack(endpoint->in); return USB_REQUEST_STATUS_OK; default: @@ -314,3 +319,70 @@ usb_request_status_t usb_vendor_request_set_hw_sync_mode( return USB_REQUEST_STATUS_OK; } } + +void rx_mode(void) { + unsigned int phase = 1; + + baseband_streaming_enable(&sgpio_config); + + while (TRANSCEIVER_MODE_RX == _transceiver_mode) { + // Set up IN transfer of buffer 0. + if (16384 <= usb_bulk_buffer_offset && 1 == phase) { + usb_transfer_schedule_block( + &usb_endpoint_bulk_in, + &usb_bulk_buffer[0x0000], + 0x4000, + NULL, NULL + ); + phase = 0; + } + // Set up IN transfer of buffer 1. + if (16384 > usb_bulk_buffer_offset && 0 == phase) { + usb_transfer_schedule_block( + &usb_endpoint_bulk_in, + &usb_bulk_buffer[0x4000], + 0x4000, + NULL, NULL + ); + phase = 1; + } + } +} + +void tx_mode(void) { + unsigned int phase = 1; + + memset(&usb_bulk_buffer[0x0000], 0, 0x8000); + // Set up OUT transfer of buffer 1. + usb_transfer_schedule_block( + &usb_endpoint_bulk_out, + &usb_bulk_buffer[0x4000], + 0x4000, + NULL, NULL + ); + // Start transmitting zeros while the host fills buffer 1. + baseband_streaming_enable(&sgpio_config); + + while (TRANSCEIVER_MODE_TX == _transceiver_mode) { + // Set up OUT transfer of buffer 0. + if (16384 <= usb_bulk_buffer_offset && 1 == phase) { + usb_transfer_schedule_block( + &usb_endpoint_bulk_out, + &usb_bulk_buffer[0x0000], + 0x4000, + NULL, NULL + ); + phase = 0; + } + // Set up OUT transfer of buffer 1. + if (16384 > usb_bulk_buffer_offset && 0 == phase) { + usb_transfer_schedule_block( + &usb_endpoint_bulk_out, + &usb_bulk_buffer[0x4000], + 0x4000, + NULL, NULL + ); + phase = 1; + } + } +} diff --git a/firmware/hackrf_usb/usb_api_transceiver.h b/firmware/hackrf_usb/usb_api_transceiver.h index eb4a5c35..968bc4ed 100644 --- a/firmware/hackrf_usb/usb_api_transceiver.h +++ b/firmware/hackrf_usb/usb_api_transceiver.h @@ -59,5 +59,7 @@ usb_request_status_t usb_vendor_request_set_hw_sync_mode( transceiver_mode_t transceiver_mode(void); void set_transceiver_mode(const transceiver_mode_t new_transceiver_mode); void start_streaming_on_hw_sync(); +void rx_mode(void); +void tx_mode(void); #endif/*__USB_API_TRANSCEIVER_H__*/ diff --git a/host/hackrf-tools/src/hackrf_sweep.c b/host/hackrf-tools/src/hackrf_sweep.c index 3d4fd043..4ab3e72f 100644 --- a/host/hackrf-tools/src/hackrf_sweep.c +++ b/host/hackrf-tools/src/hackrf_sweep.c @@ -664,13 +664,6 @@ int main(int argc, char** argv) { ifftwPlan = fftwf_plan_dft_1d(fftSize * step_count, ifftwIn, ifftwOut, FFTW_BACKWARD, FFTW_MEASURE); } - result |= hackrf_start_rx(device, rx_callback, NULL); - if (result != HACKRF_SUCCESS) { - fprintf(stderr, "hackrf_start_rx() failed: %s (%d)\n", hackrf_error_name(result), result); - usage(); - return EXIT_FAILURE; - } - result = hackrf_init_sweep(device, frequencies, num_ranges, num_samples * 2, TUNE_STEP * FREQ_ONE_MHZ, OFFSET, INTERLEAVED); if( result != HACKRF_SUCCESS ) { @@ -679,6 +672,13 @@ int main(int argc, char** argv) { return EXIT_FAILURE; } + result |= hackrf_start_rx_sweep(device, rx_callback, NULL); + if (result != HACKRF_SUCCESS) { + fprintf(stderr, "hackrf_start_rx_sweep() failed: %s (%d)\n", hackrf_error_name(result), result); + usage(); + return EXIT_FAILURE; + } + if (amp) { fprintf(stderr, "call hackrf_set_amp_enable(%u)\n", amp_enable); result = hackrf_set_amp_enable(device, (uint8_t)amp_enable); diff --git a/host/libhackrf/src/hackrf.c b/host/libhackrf/src/hackrf.c index 12c8bcc2..bc1d5fe8 100644 --- a/host/libhackrf/src/hackrf.c +++ b/host/libhackrf/src/hackrf.c @@ -96,6 +96,7 @@ typedef enum { HACKRF_TRANSCEIVER_MODE_TRANSMIT = 2, HACKRF_TRANSCEIVER_MODE_SS = 3, TRANSCEIVER_MODE_CPLD_UPDATE = 4, + TRANSCEIVER_MODE_RX_SWEEP = 5, } hackrf_transceiver_mode; typedef enum { @@ -215,6 +216,8 @@ static int allocate_transfers(hackrf_device* const device) return HACKRF_ERROR_NO_MEM; } + memset(device->buffer, 0, TRANSFER_COUNT * TRANSFER_BUFFER_SIZE); + for(transfer_index=0; transfer_indextransfers[transfer_index] = libusb_alloc_transfer(0); @@ -2162,6 +2165,20 @@ int ADDCALL hackrf_set_ui_enable(hackrf_device* device, const uint8_t value) } } +int ADDCALL hackrf_start_rx_sweep(hackrf_device* device, hackrf_sample_block_cb_fn callback, void* rx_ctx) +{ + USB_API_REQUIRED(device, 0x0104) + int result; + const uint8_t endpoint_address = LIBUSB_ENDPOINT_IN | 1; + result = hackrf_set_transceiver_mode(device, TRANSCEIVER_MODE_RX_SWEEP); + if (HACKRF_SUCCESS == result) + { + device->rx_ctx = rx_ctx; + result = create_transfer_thread(device, endpoint_address, callback); + } + return result; +} + #ifdef __cplusplus } // __cplusplus defined. #endif diff --git a/host/libhackrf/src/hackrf.h b/host/libhackrf/src/hackrf.h index 9cdf2c48..2cbac532 100644 --- a/host/libhackrf/src/hackrf.h +++ b/host/libhackrf/src/hackrf.h @@ -259,6 +259,7 @@ extern ADDAPI int ADDCALL hackrf_cpld_checksum(hackrf_device* device, #endif /* HACKRF_ISSUE_609_IS_FIXED */ extern ADDAPI int ADDCALL hackrf_set_ui_enable(hackrf_device* device, const uint8_t value); +extern ADDAPI int ADDCALL hackrf_start_rx_sweep(hackrf_device* device, hackrf_sample_block_cb_fn callback, void* rx_ctx); #ifdef __cplusplus } // __cplusplus defined.