Merge pull request #707 from miek/transceiver

Clean up transceiver modes & fix invalid data on start of TX/RX
This commit is contained in:
Michael Ossmann
2020-07-26 07:31:00 -06:00
committed by GitHub
11 changed files with 128 additions and 62 deletions

View File

@ -256,7 +256,8 @@ typedef enum {
TRANSCEIVER_MODE_RX = 1, TRANSCEIVER_MODE_RX = 1,
TRANSCEIVER_MODE_TX = 2, TRANSCEIVER_MODE_TX = 2,
TRANSCEIVER_MODE_SS = 3, TRANSCEIVER_MODE_SS = 3,
TRANSCEIVER_MODE_CPLD_UPDATE = 4 TRANSCEIVER_MODE_CPLD_UPDATE = 4,
TRANSCEIVER_MODE_RX_SWEEP = 5,
} transceiver_mode_t; } transceiver_mode_t;
typedef enum { typedef enum {

View File

@ -252,46 +252,22 @@ int main(void) {
} }
operacake_init(operacake_allow_gpio); operacake_init(operacake_allow_gpio);
unsigned int phase = 0;
usb_bulk_buffer_offset = 0;
while(true) { while(true) {
// Check whether we need to initiate a CPLD update switch (transceiver_mode()) {
if (start_cpld_update) case TRANSCEIVER_MODE_RX:
cpld_update(); rx_mode();
break;
// Check whether we need to initiate sweep mode case TRANSCEIVER_MODE_TX:
if (start_sweep_mode) { tx_mode();
start_sweep_mode = false; break;
case TRANSCEIVER_MODE_RX_SWEEP:
sweep_mode(); sweep_mode();
} break;
case TRANSCEIVER_MODE_CPLD_UPDATE:
// Set up IN transfer of buffer 0. cpld_update();
if ( usb_bulk_buffer_offset >= 16384 break;
&& phase == 1 default:
&& transceiver_mode() != TRANSCEIVER_MODE_OFF) { break;
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;
} }
} }

View File

@ -33,7 +33,6 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
volatile bool start_cpld_update = false;
uint8_t cpld_xsvf_buffer[512]; uint8_t cpld_xsvf_buffer[512];
volatile bool cpld_wait = false; volatile bool cpld_wait = false;

View File

@ -28,8 +28,6 @@
#include <usb_type.h> #include <usb_type.h>
#include <usb_request.h> #include <usb_request.h>
extern volatile bool start_cpld_update;
void cpld_update(void); void cpld_update(void);
usb_request_status_t usb_vendor_request_cpld_checksum( usb_request_status_t usb_vendor_request_cpld_checksum(

View File

@ -27,6 +27,7 @@
#include "usb_bulk_buffer.h" #include "usb_bulk_buffer.h"
#include "tuning.h" #include "tuning.h"
#include "usb_endpoint.h" #include "usb_endpoint.h"
#include "streaming.h"
#define MIN(x,y) ((x)<(y)?(x):(y)) #define MIN(x,y) ((x)<(y)?(x):(y))
#define MAX(x,y) ((x)>(y)?(x):(y)) #define MAX(x,y) ((x)>(y)?(x):(y))
@ -34,7 +35,6 @@
#define MAX_RANGES 10 #define MAX_RANGES 10
#define THROWAWAY_BUFFERS 2 #define THROWAWAY_BUFFERS 2
volatile bool start_sweep_mode = false;
static uint64_t sweep_freq; static uint64_t sweep_freq;
static uint16_t frequencies[MAX_RANGES * 2]; static uint16_t frequencies[MAX_RANGES * 2];
static unsigned char data[9 + MAX_RANGES * 2 * sizeof(frequencies[0])]; 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 uint32_t offset = 0;
static enum sweep_style style = LINEAR; 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_request_status_t usb_vendor_request_init_sweep(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) 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; sweep_freq = (uint64_t)frequencies[0] * FREQ_GRANULARITY;
set_freq(sweep_freq + offset); set_freq(sweep_freq + offset);
start_sweep_mode = true;
usb_transfer_schedule_ack(endpoint->in); usb_transfer_schedule_ack(endpoint->in);
} }
return USB_REQUEST_STATUS_OK; return USB_REQUEST_STATUS_OK;
@ -93,7 +93,9 @@ void sweep_mode(void) {
uint8_t *buffer; uint8_t *buffer;
bool transfer = false; 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. // Set up IN transfer of buffer 0.
if ( usb_bulk_buffer_offset >= 16384 && phase == 1) { if ( usb_bulk_buffer_offset >= 16384 && phase == 1) {
transfer = true; transfer = true;

View File

@ -26,8 +26,6 @@
#include <usb_type.h> #include <usb_type.h>
#include <usb_request.h> #include <usb_request.h>
extern volatile bool start_sweep_mode;
enum sweep_style { enum sweep_style {
LINEAR = 0, LINEAR = 0,
INTERLEAVED = 1, INTERLEAVED = 1,

View File

@ -36,8 +36,10 @@
#include <usb_queue.h> #include <usb_queue.h>
#include <stddef.h> #include <stddef.h>
#include <string.h>
#include "usb_endpoint.h" #include "usb_endpoint.h"
#include "usb_api_sweep.h"
typedef struct { typedef struct {
uint32_t freq_mhz; uint32_t freq_mhz;
@ -251,17 +253,22 @@ void set_transceiver_mode(const transceiver_mode_t new_transceiver_mode) {
_transceiver_mode = 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_off(LED3);
led_on(LED2); led_on(LED2);
rf_path_set_direction(&rf_path, RF_PATH_DIRECTION_RX); rf_path_set_direction(&rf_path, RF_PATH_DIRECTION_RX);
usb_bulk_buffer_tx = false; usb_bulk_buffer_tx = false;
} else if (_transceiver_mode == TRANSCEIVER_MODE_TX) { break;
case TRANSCEIVER_MODE_TX:
led_off(LED2); led_off(LED2);
led_on(LED3); led_on(LED3);
rf_path_set_direction(&rf_path, RF_PATH_DIRECTION_TX); rf_path_set_direction(&rf_path, RF_PATH_DIRECTION_TX);
usb_bulk_buffer_tx = true; usb_bulk_buffer_tx = true;
} else { break;
case TRANSCEIVER_MODE_OFF:
default:
led_off(LED2); led_off(LED2);
led_off(LED3); led_off(LED3);
rf_path_set_direction(&rf_path, RF_PATH_DIRECTION_OFF); 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); 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_OFF:
case TRANSCEIVER_MODE_RX: case TRANSCEIVER_MODE_RX:
case TRANSCEIVER_MODE_TX: case TRANSCEIVER_MODE_TX:
set_transceiver_mode(endpoint->setup.value); case TRANSCEIVER_MODE_RX_SWEEP:
usb_transfer_schedule_ack(endpoint->in);
return USB_REQUEST_STATUS_OK;
case TRANSCEIVER_MODE_CPLD_UPDATE: case TRANSCEIVER_MODE_CPLD_UPDATE:
start_cpld_update = true; set_transceiver_mode(endpoint->setup.value);
usb_transfer_schedule_ack(endpoint->in); usb_transfer_schedule_ack(endpoint->in);
return USB_REQUEST_STATUS_OK; return USB_REQUEST_STATUS_OK;
default: default:
@ -314,3 +319,70 @@ usb_request_status_t usb_vendor_request_set_hw_sync_mode(
return USB_REQUEST_STATUS_OK; 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;
}
}
}

View File

@ -59,5 +59,7 @@ usb_request_status_t usb_vendor_request_set_hw_sync_mode(
transceiver_mode_t transceiver_mode(void); transceiver_mode_t transceiver_mode(void);
void set_transceiver_mode(const transceiver_mode_t new_transceiver_mode); void set_transceiver_mode(const transceiver_mode_t new_transceiver_mode);
void start_streaming_on_hw_sync(); void start_streaming_on_hw_sync();
void rx_mode(void);
void tx_mode(void);
#endif/*__USB_API_TRANSCEIVER_H__*/ #endif/*__USB_API_TRANSCEIVER_H__*/

View File

@ -664,13 +664,6 @@ int main(int argc, char** argv) {
ifftwPlan = fftwf_plan_dft_1d(fftSize * step_count, ifftwIn, ifftwOut, FFTW_BACKWARD, FFTW_MEASURE); 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, result = hackrf_init_sweep(device, frequencies, num_ranges, num_samples * 2,
TUNE_STEP * FREQ_ONE_MHZ, OFFSET, INTERLEAVED); TUNE_STEP * FREQ_ONE_MHZ, OFFSET, INTERLEAVED);
if( result != HACKRF_SUCCESS ) { if( result != HACKRF_SUCCESS ) {
@ -679,6 +672,13 @@ int main(int argc, char** argv) {
return EXIT_FAILURE; 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) { if (amp) {
fprintf(stderr, "call hackrf_set_amp_enable(%u)\n", amp_enable); fprintf(stderr, "call hackrf_set_amp_enable(%u)\n", amp_enable);
result = hackrf_set_amp_enable(device, (uint8_t)amp_enable); result = hackrf_set_amp_enable(device, (uint8_t)amp_enable);

View File

@ -96,6 +96,7 @@ typedef enum {
HACKRF_TRANSCEIVER_MODE_TRANSMIT = 2, HACKRF_TRANSCEIVER_MODE_TRANSMIT = 2,
HACKRF_TRANSCEIVER_MODE_SS = 3, HACKRF_TRANSCEIVER_MODE_SS = 3,
TRANSCEIVER_MODE_CPLD_UPDATE = 4, TRANSCEIVER_MODE_CPLD_UPDATE = 4,
TRANSCEIVER_MODE_RX_SWEEP = 5,
} hackrf_transceiver_mode; } hackrf_transceiver_mode;
typedef enum { typedef enum {
@ -215,6 +216,8 @@ static int allocate_transfers(hackrf_device* const device)
return HACKRF_ERROR_NO_MEM; return HACKRF_ERROR_NO_MEM;
} }
memset(device->buffer, 0, TRANSFER_COUNT * TRANSFER_BUFFER_SIZE);
for(transfer_index=0; transfer_index<TRANSFER_COUNT; transfer_index++) for(transfer_index=0; transfer_index<TRANSFER_COUNT; transfer_index++)
{ {
device->transfers[transfer_index] = libusb_alloc_transfer(0); device->transfers[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 #ifdef __cplusplus
} // __cplusplus defined. } // __cplusplus defined.
#endif #endif

View File

@ -259,6 +259,7 @@ extern ADDAPI int ADDCALL hackrf_cpld_checksum(hackrf_device* device,
#endif /* HACKRF_ISSUE_609_IS_FIXED */ #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_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 #ifdef __cplusplus
} // __cplusplus defined. } // __cplusplus defined.