From 1b8e1d18c55214acfcb8af18508b5e5795f1709b Mon Sep 17 00:00:00 2001 From: Dominic Spill Date: Sun, 24 Jul 2016 14:32:55 +0100 Subject: [PATCH] Add scan mode function separate to main loop --- firmware/hackrf_usb/hackrf_usb.c | 113 ++++------------------ firmware/hackrf_usb/usb_api_scan.c | 81 ++++++++++++++-- firmware/hackrf_usb/usb_api_scan.h | 4 +- firmware/hackrf_usb/usb_api_transceiver.c | 72 ++++++++++++++ firmware/hackrf_usb/usb_api_transceiver.h | 5 + 5 files changed, 171 insertions(+), 104 deletions(-) diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index c5dea94c..25dff4ee 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -22,8 +22,6 @@ #include -#include - #include #include @@ -45,73 +43,8 @@ #include "usb_api_scan.h" #include "usb_api_transceiver.h" -#include "sgpio_isr.h" #include "usb_bulk_buffer.h" -static volatile transceiver_mode_t _transceiver_mode = TRANSCEIVER_MODE_OFF; - -void set_transceiver_mode(const transceiver_mode_t new_transceiver_mode) { - baseband_streaming_disable(&sgpio_config); - - usb_endpoint_disable(&usb_endpoint_bulk_in); - usb_endpoint_disable(&usb_endpoint_bulk_out); - - _transceiver_mode = new_transceiver_mode; - - if( _transceiver_mode == TRANSCEIVER_MODE_RX ) { - led_off(LED3); - led_on(LED2); - usb_endpoint_init(&usb_endpoint_bulk_in); - rf_path_set_direction(&rf_path, RF_PATH_DIRECTION_RX); - vector_table.irq[NVIC_SGPIO_IRQ] = sgpio_isr_rx; - } else if (_transceiver_mode == TRANSCEIVER_MODE_TX) { - led_off(LED2); - led_on(LED3); - usb_endpoint_init(&usb_endpoint_bulk_out); - rf_path_set_direction(&rf_path, RF_PATH_DIRECTION_TX); - vector_table.irq[NVIC_SGPIO_IRQ] = sgpio_isr_tx; - } else { - led_off(LED2); - led_off(LED3); - rf_path_set_direction(&rf_path, RF_PATH_DIRECTION_OFF); - vector_table.irq[NVIC_SGPIO_IRQ] = sgpio_isr_rx; - } - - if( _transceiver_mode != TRANSCEIVER_MODE_OFF ) { - si5351c_activate_best_clock_source(&clock_gen); - baseband_streaming_enable(&sgpio_config); - } -} - -transceiver_mode_t transceiver_mode(void) { - return _transceiver_mode; -} - -usb_request_status_t usb_vendor_request_set_transceiver_mode( - usb_endpoint_t* const endpoint, - const usb_transfer_stage_t stage -) { - if( stage == USB_TRANSFER_STAGE_SETUP ) { - switch( endpoint->setup.value ) { - 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_CPLD_UPDATE: - usb_endpoint_init(&usb_endpoint_bulk_out); - start_cpld_update = true; - usb_transfer_schedule_ack(endpoint->in); - return USB_REQUEST_STATUS_OK; - default: - return USB_REQUEST_STATUS_STALL; - } - } else { - return USB_REQUEST_STATUS_OK; - } -} - static const usb_request_handler_fn vendor_request_handler[] = { NULL, usb_vendor_request_set_transceiver_mode, @@ -243,50 +176,44 @@ int main(void) { rf_path_init(&rf_path); unsigned int phase = 0; - unsigned int blocks_queued = 0; while(true) { // Check whether we need to initiate a CPLD update if (start_cpld_update) cpld_update(); + // Check whether we need to initiate scan mode + if (start_scan_mode) + scan_mode(); + // Set up IN transfer of buffer 0. if ( usb_bulk_buffer_offset >= 16384 && phase == 1 && transceiver_mode() != TRANSCEIVER_MODE_OFF) { - if (blocks_queued == 2) - usb_transfer_schedule_block( - (transceiver_mode() == TRANSCEIVER_MODE_RX) - ? &usb_endpoint_bulk_in : &usb_endpoint_bulk_out, - &usb_bulk_buffer[0x0000], - 0x4000, - NULL, NULL - ); + 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; - blocks_queued++; } - + // Set up IN transfer of buffer 1. if ( usb_bulk_buffer_offset < 16384 && phase == 0 && transceiver_mode() != TRANSCEIVER_MODE_OFF) { - if (blocks_queued == 2) - usb_transfer_schedule_block( - (transceiver_mode() == TRANSCEIVER_MODE_RX) - ? &usb_endpoint_bulk_in : &usb_endpoint_bulk_out, - &usb_bulk_buffer[0x4000], - 0x4000, - NULL, NULL - ); + 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; - blocks_queued++; - } - - if (blocks_queued > 2) { - scan_callback(); - blocks_queued = 0; } } - + return 0; } diff --git a/firmware/hackrf_usb/usb_api_scan.c b/firmware/hackrf_usb/usb_api_scan.c index 376a17f7..14298996 100644 --- a/firmware/hackrf_usb/usb_api_scan.c +++ b/firmware/hackrf_usb/usb_api_scan.c @@ -22,32 +22,95 @@ #include "usb_api_scan.h" #include "usb_queue.h" #include -//#include +#include +#include "usb_api_transceiver.h" +#include "usb_bulk_buffer.h" #include "tuning.h" +#include "usb_endpoint.h" -volatile bool scan_mode = false; +#define MIN(x,y) ((x)<(y)?(x):(y)) +#define MAX(x,y) ((x)>(y)?(x):(y)) +#define MIN_FREQ 1000000 +#define MAX_FREQ 6000000000 + +volatile bool start_scan_mode = false; static uint64_t scan_freq; static uint64_t scan_freq_min; static uint64_t scan_freq_max; static uint64_t scan_freq_step; +static inline uint64_t bytes_to_uint64(uint8_t* buf) { + uint64_t tmp = buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3]; + tmp <<= 32; + tmp |= buf[4] << 24 | buf[5] << 16 | buf[6] << 8 | buf[7]; + return tmp; +} + usb_request_status_t usb_vendor_request_init_scan( usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) { - if (stage == USB_TRANSFER_STAGE_SETUP) { + uint64_t freqs[3]; + if ((stage == USB_TRANSFER_STAGE_SETUP) && + (endpoint->setup.length == 24)) { // DGS set scan frequencies here + //freq_min = bytes_to_uint64(); + usb_transfer_schedule_block(endpoint->out, &freqs, 3*sizeof(uint64_t), + NULL, NULL); + + scan_freq_min = MAX(MIN_FREQ, freqs[0]); + scan_freq_max = MIN(MAX_FREQ, freqs[1]); + scan_freq_step = freqs[2]; + scan_freq = scan_freq_min; set_freq(scan_freq); - scan_mode = true; + start_scan_mode = true; usb_transfer_schedule_ack(endpoint->in); } return USB_REQUEST_STATUS_OK; } -void scan_callback(void) { - scan_freq += scan_freq_step; - if (scan_freq > scan_freq_max) { - scan_freq = scan_freq_min; +void scan_mode(void) { + unsigned int blocks_queued = 0; + unsigned int phase = 0; + + while(transceiver_mode() != TRANSCEIVER_MODE_OFF) { + // 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; + blocks_queued++; } - set_freq(scan_freq); + + // 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; + blocks_queued++; + } + + if (blocks_queued > 2) { + scan_freq += scan_freq_step; + if (scan_freq > scan_freq_max) { + scan_freq = scan_freq_min; + } + set_freq(scan_freq); + blocks_queued = 0; + } + } } diff --git a/firmware/hackrf_usb/usb_api_scan.h b/firmware/hackrf_usb/usb_api_scan.h index 3aca5372..be066612 100644 --- a/firmware/hackrf_usb/usb_api_scan.h +++ b/firmware/hackrf_usb/usb_api_scan.h @@ -26,11 +26,11 @@ #include #include -extern volatile bool scan_mode; +extern volatile bool start_scan_mode; usb_request_status_t usb_vendor_request_init_scan( usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); -void scan_callback(void); +void scan_mode(void); #endif /* __USB_API_SPCAN_H__ */ diff --git a/firmware/hackrf_usb/usb_api_transceiver.c b/firmware/hackrf_usb/usb_api_transceiver.c index e8bac410..d86de7db 100644 --- a/firmware/hackrf_usb/usb_api_transceiver.c +++ b/firmware/hackrf_usb/usb_api_transceiver.c @@ -22,9 +22,16 @@ #include "usb_api_transceiver.h" +#include +#include +#include "sgpio_isr.h" + +#include "usb_api_cpld.h" // Remove when CPLD update is handled elsewhere + #include #include #include +#include #include #include @@ -221,3 +228,68 @@ usb_request_status_t usb_vendor_request_set_freq_explicit( return USB_REQUEST_STATUS_OK; } } + +static volatile transceiver_mode_t _transceiver_mode = TRANSCEIVER_MODE_OFF; + + +transceiver_mode_t transceiver_mode(void) { + return _transceiver_mode; +} + +void set_transceiver_mode(const transceiver_mode_t new_transceiver_mode) { + baseband_streaming_disable(&sgpio_config); + + usb_endpoint_disable(&usb_endpoint_bulk_in); + usb_endpoint_disable(&usb_endpoint_bulk_out); + + _transceiver_mode = new_transceiver_mode; + + if( _transceiver_mode == TRANSCEIVER_MODE_RX ) { + led_off(LED3); + led_on(LED2); + usb_endpoint_init(&usb_endpoint_bulk_in); + rf_path_set_direction(&rf_path, RF_PATH_DIRECTION_RX); + vector_table.irq[NVIC_SGPIO_IRQ] = sgpio_isr_rx; + } else if (_transceiver_mode == TRANSCEIVER_MODE_TX) { + led_off(LED2); + led_on(LED3); + usb_endpoint_init(&usb_endpoint_bulk_out); + rf_path_set_direction(&rf_path, RF_PATH_DIRECTION_TX); + vector_table.irq[NVIC_SGPIO_IRQ] = sgpio_isr_tx; + } else { + led_off(LED2); + led_off(LED3); + rf_path_set_direction(&rf_path, RF_PATH_DIRECTION_OFF); + vector_table.irq[NVIC_SGPIO_IRQ] = sgpio_isr_rx; + } + + if( _transceiver_mode != TRANSCEIVER_MODE_OFF ) { + si5351c_activate_best_clock_source(&clock_gen); + baseband_streaming_enable(&sgpio_config); + } +} + +usb_request_status_t usb_vendor_request_set_transceiver_mode( + usb_endpoint_t* const endpoint, + const usb_transfer_stage_t stage +) { + if( stage == USB_TRANSFER_STAGE_SETUP ) { + switch( endpoint->setup.value ) { + 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_CPLD_UPDATE: + usb_endpoint_init(&usb_endpoint_bulk_out); + start_cpld_update = true; + usb_transfer_schedule_ack(endpoint->in); + return USB_REQUEST_STATUS_OK; + default: + return USB_REQUEST_STATUS_STALL; + } + } else { + return USB_REQUEST_STATUS_OK; + } +} \ No newline at end of file diff --git a/firmware/hackrf_usb/usb_api_transceiver.h b/firmware/hackrf_usb/usb_api_transceiver.h index 24244025..59f85778 100644 --- a/firmware/hackrf_usb/usb_api_transceiver.h +++ b/firmware/hackrf_usb/usb_api_transceiver.h @@ -53,4 +53,9 @@ usb_request_status_t usb_vendor_request_set_antenna_enable( usb_request_status_t usb_vendor_request_set_freq_explicit( usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); +transceiver_mode_t transceiver_mode(void); +void set_transceiver_mode(const transceiver_mode_t new_transceiver_mode); +usb_request_status_t usb_vendor_request_set_transceiver_mode( + usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); + #endif/*__USB_API_TRANSCEIVER_H__*/