diff --git a/.gitignore b/.gitignore index 0c016b75..b2507075 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,7 @@ Thumbs.db *.swp *.sublime-project *.sublime-workspace +.vscode* # Xilinx tools create an enormous amount of poop: firmware/cpld/**/isim/ diff --git a/firmware/common/sgpio_dma.c b/firmware/common/sgpio_dma.c deleted file mode 100644 index dc78ddf1..00000000 --- a/firmware/common/sgpio_dma.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright 2013 Jared Boone - * - * This file is part of HackRF. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#include - -#include -#include -#include -#include - -#include -#include - -void sgpio_dma_configure_lli( - gpdma_lli_t* const lli, - const size_t lli_count, - const bool direction_transmit, - void* const buffer, - const size_t transfer_bytes -) { - const size_t bytes_per_word = 4; - const size_t transfer_words = (transfer_bytes + bytes_per_word - 1) / bytes_per_word; - - gpdma_lli_create_loop(lli, lli_count); - - for(size_t i=0; icsrcaddr; - GPDMA_CDESTADDR(channel) = (uint32_t)lli->cdestaddr; - GPDMA_CLLI(channel) = (uint32_t)lli->clli; - GPDMA_CCONTROL(channel) = lli->ccontrol; - - /* 1: Memory -> Peripheral - * 2: Peripheral -> Memory */ - const uint_fast8_t flowcntrl = direction_transmit ? 1 : 2; - - GPDMA_CCONFIG(channel) = - GPDMA_CCONFIG_E(0) | - GPDMA_CCONFIG_SRCPERIPHERAL(0) | - GPDMA_CCONFIG_DESTPERIPHERAL(0) | - GPDMA_CCONFIG_FLOWCNTRL(flowcntrl) | - GPDMA_CCONFIG_IE(1) | - GPDMA_CCONFIG_ITC(1) | - GPDMA_CCONFIG_L(0) | - GPDMA_CCONFIG_H(0) - ; - - gpdma_channel_enable(channel); -} - -void sgpio_dma_init() { - /* DMA peripheral/source 0, option 2 (SGPIO14) -- BREQ */ - CREG_DMAMUX &= ~(CREG_DMAMUX_DMAMUXPER0_MASK); - CREG_DMAMUX |= CREG_DMAMUX_DMAMUXPER0(0x2); - - // Disable sync, maybe it is causing max speed (10MT/sec) glitches? - //GPDMA_DMACSYNC = (1 << 0); - //GPDMA_SYNC = GPDMA_SYNC_DMACSYNC(0xFFFF); // TODO: Don't do this, I'm just going nuts here. - - gpdma_controller_enable(); -} - -static const uint_fast8_t dma_channel_sgpio = 0; - -void sgpio_dma_rx_start(const gpdma_lli_t* const start_lli) { - sgpio_dma_enable(dma_channel_sgpio, start_lli, false); -} - -void sgpio_dma_tx_start(const gpdma_lli_t* const start_lli) { - sgpio_dma_enable(dma_channel_sgpio, start_lli, true); -} - -void sgpio_dma_irq_tc_acknowledge() { - gpdma_channel_interrupt_tc_clear(dma_channel_sgpio); -} - -void sgpio_dma_stop() { - gpdma_channel_disable(dma_channel_sgpio); -} - -size_t sgpio_dma_current_transfer_index( - const gpdma_lli_t* const lli, - const size_t lli_count -) { - const uint32_t next_lli = GPDMA_CLLI(dma_channel_sgpio); - for(size_t i=0; i - * - * This file is part of HackRF. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifndef __SGPIO_DMA_H__ -#define __SGPIO_DMA_H__ - -#include - -#include - -void sgpio_dma_configure_lli( - gpdma_lli_t* const lli, - const size_t lli_count, - const bool direction_transmit, - void* const buffer, - const size_t transfer_bytes -); - -void sgpio_dma_init(); -void sgpio_dma_rx_start(const gpdma_lli_t* const start_lli); -void sgpio_dma_tx_start(const gpdma_lli_t* const start_lli); -void sgpio_dma_irq_tc_acknowledge(); -void sgpio_dma_stop(); - -size_t sgpio_dma_current_transfer_index( - const gpdma_lli_t* const lli, - const size_t lli_count -); - -#endif/*__SGPIO_DMA_H__*/ diff --git a/firmware/common/usb.c b/firmware/common/usb.c index fb7b2547..f8e4bd8c 100644 --- a/firmware/common/usb.c +++ b/firmware/common/usb.c @@ -320,8 +320,7 @@ static void usb_controller_set_device_mode() { // Set device-related OTG flags // OTG termination: controls pull-down on USB_DM - // VBUS_Discharge: VBUS discharges through resistor - USB0_OTGSC = USB0_OTGSC_OT | USB0_OTGSC_VD; + USB0_OTGSC = USB0_OTGSC_OT; } usb_speed_t usb_speed( diff --git a/firmware/hackrf_usb/usb_api_sweep.c b/firmware/hackrf_usb/usb_api_sweep.c index 581faacc..503e7f6a 100644 --- a/firmware/hackrf_usb/usb_api_sweep.c +++ b/firmware/hackrf_usb/usb_api_sweep.c @@ -34,6 +34,7 @@ #define MIN_FREQ 1 #define MAX_FREQ 6000 #define MAX_FREQ_COUNT 1000 +#define THROWAWAY_BUFFERS 2 volatile bool start_sweep_mode = false; static uint64_t sweep_freq; @@ -89,16 +90,18 @@ void sweep_mode(void) { if (transfer) { *(uint16_t*)buffer = 0x7F7F; *(uint16_t*)(buffer+2) = sweep_freq; - usb_transfer_schedule_block( - &usb_endpoint_bulk_in, - buffer, - 0x4000, - NULL, NULL - ); + if (blocks_queued > THROWAWAY_BUFFERS) { + usb_transfer_schedule_block( + &usb_endpoint_bulk_in, + buffer, + 0x4000, + NULL, NULL + ); + } transfer = false; } - if (blocks_queued >= dwell_blocks) { + if ((dwell_blocks + THROWAWAY_BUFFERS) <= blocks_queued) { if(++ifreq >= frequency_count) ifreq = 0; sweep_freq = frequencies[ifreq]; diff --git a/firmware/hackrf_usb/usb_descriptor.c b/firmware/hackrf_usb/usb_descriptor.c index cbf267e5..f11ce887 100644 --- a/firmware/hackrf_usb/usb_descriptor.c +++ b/firmware/hackrf_usb/usb_descriptor.c @@ -57,7 +57,7 @@ uint8_t usb_descriptor_device[] = { USB_MAX_PACKET0, // bMaxPacketSize0 USB_WORD(USB_VENDOR_ID), // idVendor USB_WORD(USB_PRODUCT_ID), // idProduct - USB_WORD(0x0101), // bcdDevice + USB_WORD(0x0102), // bcdDevice 0x01, // iManufacturer 0x02, // iProduct 0x04, // iSerialNumber diff --git a/host/hackrf-tools/src/CMakeLists.txt b/host/hackrf-tools/src/CMakeLists.txt index d8f602c1..00a173fc 100644 --- a/host/hackrf-tools/src/CMakeLists.txt +++ b/host/hackrf-tools/src/CMakeLists.txt @@ -25,16 +25,6 @@ set(INSTALL_DEFAULT_BINDIR "bin" CACHE STRING "Appended to CMAKE_INSTALL_PREFIX" INCLUDE(FindPkgConfig) -if(MSVC) - add_library(libgetopt_static STATIC - ../getopt/getopt.c - ) -else() - pkg_check_modules(FFTW REQUIRED fftw3f) - LIST(APPEND TOOLS hackrf_sweep) - LIST(APPEND TOOLS_LINK_LIBS m fftw3f) -endif() - SET(TOOLS hackrf_max2837 hackrf_si5351c @@ -46,6 +36,16 @@ SET(TOOLS hackrf_operacake ) +if(MSVC) + add_library(libgetopt_static STATIC + ../getopt/getopt.c + ) +else() + pkg_check_modules(FFTW REQUIRED fftw3f) + LIST(APPEND TOOLS hackrf_sweep) + LIST(APPEND TOOLS_LINK_LIBS m fftw3f) +endif() + if(NOT libhackrf_SOURCE_DIR) include_directories(${LIBHACKRF_INCLUDE_DIR}) LIST(APPEND TOOLS_LINK_LIBS ${LIBHACKRF_LIBRARIES}) diff --git a/host/hackrf-tools/src/hackrf_cpldjtag.c b/host/hackrf-tools/src/hackrf_cpldjtag.c index b76c9349..fc82deb4 100644 --- a/host/hackrf-tools/src/hackrf_cpldjtag.c +++ b/host/hackrf-tools/src/hackrf_cpldjtag.c @@ -45,6 +45,8 @@ uint8_t data[MAX_XSVF_LENGTH]; static struct option long_options[] = { { "xsvf", required_argument, 0, 'x' }, + { "device", required_argument, 0, 'd' }, + { "help", no_argument, 0, 'h' }, { 0, 0, 0, 0 }, }; @@ -79,8 +81,9 @@ int parse_int(char* s, uint32_t* const value) static void usage() { printf("Usage:\n"); - printf("\t-x : XSVF file to be written to CPLD.\n"); - printf("\t-d : Serial number of device, if multiple devices\n"); + printf("\t-h, --help: this help\n"); + printf("\t-x, --xsvf : XSVF file to be written to CPLD.\n"); + printf("\t-d, --device : Serial number of device, if multiple devices\n"); } int main(int argc, char** argv) @@ -97,7 +100,7 @@ int main(int argc, char** argv) ssize_t bytes_read; uint8_t* pdata = &data[0]; - while ((opt = getopt_long(argc, argv, "x:d:", long_options, + while ((opt = getopt_long(argc, argv, "x:d:h?", long_options, &option_index)) != EOF) { switch (opt) { case 'x': @@ -107,8 +110,13 @@ int main(int argc, char** argv) case 'd': serial_number = optarg; break; + case 'h': + case '?': + usage(); + return EXIT_SUCCESS; default: + fprintf(stderr, "unknown argument '-%c %s'\n", opt, optarg); usage(); return EXIT_FAILURE; } diff --git a/host/hackrf-tools/src/hackrf_info.c b/host/hackrf-tools/src/hackrf_info.c index def5371d..0049a3e7 100644 --- a/host/hackrf-tools/src/hackrf_info.c +++ b/host/hackrf-tools/src/hackrf_info.c @@ -31,6 +31,7 @@ int main(void) int result = HACKRF_SUCCESS; uint8_t board_id = BOARD_ID_INVALID; char version[255 + 1]; + uint16_t usb_version; read_partid_serialno_t read_partid_serialno; uint8_t operacakes[8]; hackrf_device_list_t *list; @@ -55,10 +56,11 @@ int main(void) if (i > 0) printf("\n"); - printf("Found HackRF board %d:\n", i); + printf("Found HackRF\n"); + printf("Index: %d\n", i); if (list->serial_numbers[i]) - printf("USB descriptor string: %s\n", list->serial_numbers[i]); + printf("Serial number: %s\n", list->serial_numbers[i]); device = NULL; result = hackrf_device_list_open(list, i, &device); @@ -83,7 +85,15 @@ int main(void) hackrf_error_name(result), result); return EXIT_FAILURE; } - printf("Firmware Version: %s\n", version); + + result = hackrf_usb_api_version_read(device, &usb_version); + if (result != HACKRF_SUCCESS) { + fprintf(stderr, "hackrf_usb_api_version_read() failed: %s (%d)\n", + hackrf_error_name(result), result); + return EXIT_FAILURE; + } + printf("Firmware Version: %s (API:%x.%02x)\n", version, + (usb_version>>8)&0xFF, usb_version&0xFF); result = hackrf_board_partid_serialno_read(device, &read_partid_serialno); if (result != HACKRF_SUCCESS) { @@ -94,23 +104,19 @@ int main(void) printf("Part ID Number: 0x%08x 0x%08x\n", read_partid_serialno.part_id[0], read_partid_serialno.part_id[1]); - printf("Serial Number: 0x%08x 0x%08x 0x%08x 0x%08x\n", - read_partid_serialno.serial_no[0], - read_partid_serialno.serial_no[1], - read_partid_serialno.serial_no[2], - read_partid_serialno.serial_no[3]); result = hackrf_get_operacake_boards(device, &operacakes[0]); - if (result != HACKRF_SUCCESS) { + if ((result != HACKRF_SUCCESS) && (result != HACKRF_ERROR_USB_API_VERSION)) { fprintf(stderr, "hackrf_get_operacake_boards() failed: %s (%d)\n", hackrf_error_name(result), result); - return EXIT_FAILURE; + return EXIT_FAILURE; } - for(j=0; j<8; j++) { - if(operacakes[j] == 0) - break; - printf("Operacake found, address: 0x%02x\n", operacakes[j]); - + if(result == HACKRF_SUCCESS) { + for(j=0; j<8; j++) { + if(operacakes[j] == 0) + break; + printf("Operacake found, address: 0x%02x\n", operacakes[j]); + } } result = hackrf_close(device); diff --git a/host/hackrf-tools/src/hackrf_max2837.c b/host/hackrf-tools/src/hackrf_max2837.c index d8fb75f5..d09a7557 100644 --- a/host/hackrf-tools/src/hackrf_max2837.c +++ b/host/hackrf-tools/src/hackrf_max2837.c @@ -26,9 +26,16 @@ #include #include +#ifndef bool +typedef int bool; +#define true 1 +#define false 0 +#endif + static void usage() { printf("\nUsage:\n"); - printf("\t-n, --register : set register number for subsequent read/write operations\n"); + printf("\t-h, --help: this help\n"); + printf("\t-n, --register : set register number for read/write operations\n"); printf("\t-r, --read: read register specified by last -n argument, or all registers\n"); printf("\t-w, --write : write register specified by last -n argument with value \n"); printf("\nExamples:\n"); @@ -41,6 +48,7 @@ static struct option long_options[] = { { "register", required_argument, 0, 'n' }, { "write", required_argument, 0, 'w' }, { "read", no_argument, 0, 'r' }, + { "help", no_argument, 0, 'h' }, { 0, 0, 0, 0 }, }; @@ -94,7 +102,7 @@ int dump_registers(hackrf_device* device) { break; } } - + return result; } @@ -123,57 +131,84 @@ int main(int argc, char** argv) { uint16_t register_value; hackrf_device* device = NULL; int option_index = 0; + bool read = false; + bool write = false; int result = hackrf_init(); if( result ) { printf("hackrf_init() failed: %s (%d)\n", hackrf_error_name(result), result); - return -1; - } - - result = hackrf_open(&device); - if( result ) { - printf("hackrf_open() failed: %s (%d)\n", hackrf_error_name(result), result); - return -1; + return EXIT_FAILURE; } - while( (opt = getopt_long(argc, argv, "n:rw:", long_options, &option_index)) != EOF ) { + while( (opt = getopt_long(argc, argv, "n:rw:h?", long_options, &option_index)) != EOF ) { switch( opt ) { case 'n': result = parse_int(optarg, ®ister_number); break; case 'w': + write = true; result = parse_int(optarg, ®ister_value); - if( result == HACKRF_SUCCESS ) { - result = write_register(device, register_number, register_value); - } break; - + case 'r': - if( register_number == REGISTER_INVALID ) { - result = dump_registers(device); - } else { - result = dump_register(device, register_number); - } + read = true; break; - - default: + + case 'h': + case '?': usage(); + return EXIT_SUCCESS; + default: + fprintf(stderr, "unknown argument '-%c %s'\n", opt, optarg); + usage(); + return EXIT_FAILURE; } - + if( result != HACKRF_SUCCESS ) { printf("argument error: %s (%d)\n", hackrf_error_name(result), result); - break; + usage(); + return EXIT_FAILURE; } } - + + if(write && read) { + fprintf(stderr, "Read and write options are mutually exclusive.\n"); + usage(); + return EXIT_FAILURE; + } + + if(!(write || read)) { + fprintf(stderr, "Specify either read or write option.\n"); + usage(); + return EXIT_FAILURE; + } + + result = hackrf_open(&device); + if(result) { + printf("hackrf_open() failed: %s (%d)\n", hackrf_error_name(result), result); + return EXIT_FAILURE; + } + + if(write) { + result = write_register(device, register_number, register_value); + } + + if(read) { + if(register_number == REGISTER_INVALID) { + result = dump_registers(device); + } else { + result = dump_register(device, register_number); + } + } + result = hackrf_close(device); if( result ) { printf("hackrf_close() failed: %s (%d)\n", hackrf_error_name(result), result); - return -1; + return EXIT_FAILURE; } - + hackrf_exit(); - return 0; + return EXIT_SUCCESS; } diff --git a/host/hackrf-tools/src/hackrf_operacake.c b/host/hackrf-tools/src/hackrf_operacake.c index 086af5cb..91e1e0d2 100644 --- a/host/hackrf-tools/src/hackrf_operacake.c +++ b/host/hackrf-tools/src/hackrf_operacake.c @@ -33,18 +33,21 @@ typedef int bool; static void usage() { printf("\nUsage:\n"); + printf("\t-h, --help: this help\n"); printf("\t-s, --serial : specify a particular device by serial number\n"); printf("\t-d, --device : specify a particular device by number\n"); printf("\t-o, --address : specify a particular operacake by address [default: 0x00]\n"); printf("\t-a : set port A connection\n"); printf("\t-b : set port B connection\n"); - printf("\t-v: verbose, list available operacake boards\n"); + printf("\t-l, --list: list available operacake boards\n"); } static struct option long_options[] = { { "device", no_argument, 0, 'd' }, { "serial", no_argument, 0, 's' }, { "address", no_argument, 0, 'o' }, + { "list", no_argument, 0, 'v' }, + { "help", no_argument, 0, 'h' }, { 0, 0, 0, 0 }, }; @@ -66,8 +69,10 @@ int main(int argc, char** argv) { int operacake_address = 0; int port_a = 0; int port_b = 0; - int verbose = 0; + bool set_ports = false; + bool list = false; uint8_t operacakes[8]; + uint8_t operacake_count = 0; int i = 0; hackrf_device* device = NULL; int option_index = 0; @@ -78,7 +83,7 @@ int main(int argc, char** argv) { return -1; } - while( (opt = getopt_long(argc, argv, "d:s:o:a:b:v", long_options, &option_index)) != EOF ) { + while( (opt = getopt_long(argc, argv, "d:s:o:a:b:lh?", long_options, &option_index)) != EOF ) { switch( opt ) { case 'd': device_index = atoi(optarg); @@ -90,6 +95,7 @@ int main(int argc, char** argv) { case 'o': operacake_address = atoi(optarg); + set_ports = true; break; case 'a': @@ -100,12 +106,18 @@ int main(int argc, char** argv) { port_b = atoi(optarg); break; - case 'v': - verbose = 1; + case 'l': + list = true; break; + case 'h': + case '?': + usage(); + return EXIT_SUCCESS; default: + fprintf(stderr, "unknown argument '-%c %s'\n", opt, optarg); usage(); + return EXIT_FAILURE; } if( result != HACKRF_SUCCESS ) { @@ -114,6 +126,12 @@ int main(int argc, char** argv) { } } + if(!(list || set_ports)) { + fprintf(stderr, "Specify either list or address option.\n"); + usage(); + return EXIT_FAILURE; + } + if(serial_number != NULL) { result = hackrf_open_by_serial(serial_number, &device); } else { @@ -130,20 +148,31 @@ int main(int argc, char** argv) { return -1; } - if(verbose) { - hackrf_get_operacake_boards(device, operacakes); - printf("Operacakes found:\n"); - for(i=0; i<8; i++) { - if(operacakes[i] !=0) - printf("%d\n", operacakes[i]); + if(list) { + result = hackrf_get_operacake_boards(device, operacakes); + if (result != HACKRF_SUCCESS) { + fprintf(stderr, "hackrf_get_operacake_boards() failed: %s (%d)\n", + hackrf_error_name(result), result); + return EXIT_FAILURE; } + printf("Operacakes found: "); + for(i=0; i<8; i++) { + if(operacakes[i] !=0) { + printf("\n%d", operacakes[i]); + operacake_count++; + } + } + if(!operacake_count) + printf("None"); printf("\n"); } - result = hackrf_set_operacake_ports(device, operacake_address, port_a, port_b); - if( result ) { - printf("hackrf_set_operacake_ports() failed: %s (%d)\n", hackrf_error_name(result), result); - return -1; + if(set_ports) { + result = hackrf_set_operacake_ports(device, operacake_address, port_a, port_b); + if( result ) { + printf("hackrf_set_operacake_ports() failed: %s (%d)\n", hackrf_error_name(result), result); + return -1; + } } result = hackrf_close(device); @@ -151,8 +180,6 @@ int main(int argc, char** argv) { printf("hackrf_close() failed: %s (%d)\n", hackrf_error_name(result), result); return -1; } - hackrf_exit(); - return 0; } diff --git a/host/hackrf-tools/src/hackrf_rffc5071.c b/host/hackrf-tools/src/hackrf_rffc5071.c index c9630dd4..11285d83 100644 --- a/host/hackrf-tools/src/hackrf_rffc5071.c +++ b/host/hackrf-tools/src/hackrf_rffc5071.c @@ -27,9 +27,16 @@ #include #include +#ifndef bool +typedef int bool; +#define true 1 +#define false 0 +#endif + static void usage() { printf("\nUsage:\n"); - printf("\t-n, --register : set register number for subsequent read/write operations\n"); + printf("\t-h, --help: this help\n"); + printf("\t-n, --register : set register number for read/write operations\n"); printf("\t-r, --read: read register specified by last -n argument, or all registers\n"); printf("\t-w, --write : write register specified by last -n argument with value \n"); printf("\nExamples:\n"); @@ -42,6 +49,7 @@ static struct option long_options[] = { { "register", required_argument, 0, 'n' }, { "write", required_argument, 0, 'w' }, { "read", no_argument, 0, 'r' }, + { "help", no_argument, 0, 'h' }, { 0, 0, 0, 0 }, }; @@ -124,58 +132,81 @@ int main(int argc, char** argv) { uint16_t register_value; hackrf_device* device = NULL; int option_index = 0; + bool read = false; + bool write = false; int result = hackrf_init(); if( result ) { printf("hackrf_init() failed: %s (%d)\n", hackrf_error_name(result), result); - return -1; - } - - result = hackrf_open(&device); - if( result ) { - printf("hackrf_open() failed: %s (%d)\n", hackrf_error_name(result), result); - return -1; + return EXIT_FAILURE; } - while( (opt = getopt_long(argc, argv, "n:rw:", long_options, &option_index)) != EOF ) { + while( (opt = getopt_long(argc, argv, "n:rw:h?", long_options, &option_index)) != EOF ) { switch( opt ) { case 'n': result = parse_int(optarg, ®ister_number); break; - case 'w': + write = true; result = parse_int(optarg, ®ister_value); - if( result == HACKRF_SUCCESS ) { - result = write_register(device, register_number, register_value); - } break; - case 'r': - if( register_number == REGISTER_INVALID ) { - result = dump_registers(device); - } else { - result = dump_register(device, register_number); - } + read = true; break; - - default: + case 'h': + case '?': usage(); + return EXIT_SUCCESS; + default: + fprintf(stderr, "unknown argument '-%c %s'\n", opt, optarg); + usage(); + return EXIT_FAILURE; } - + if( result != HACKRF_SUCCESS ) { printf("argument error: %s (%d)\n", hackrf_error_name(result), result); usage(); - break; + return EXIT_FAILURE; } } - + + if(write && read) { + fprintf(stderr, "Read and write options are mutually exclusive.\n"); + usage(); + return EXIT_FAILURE; + } + + if(!(write || read)) { + fprintf(stderr, "Specify either read or write option.\n"); + usage(); + return EXIT_FAILURE; + } + + result = hackrf_open(&device); + if(result) { + printf("hackrf_open() failed: %s (%d)\n", hackrf_error_name(result), result); + return EXIT_FAILURE; + } + + if(write) { + result = write_register(device, register_number, register_value); + } + + if(read) { + if(register_number == REGISTER_INVALID) { + result = dump_registers(device); + } else { + result = dump_register(device, register_number); + } + } + result = hackrf_close(device); if( result ) { printf("hackrf_close() failed: %s (%d)\n", hackrf_error_name(result), result); - return -1; + return EXIT_FAILURE; } - + hackrf_exit(); - - return 0; + + return EXIT_SUCCESS; } diff --git a/host/hackrf-tools/src/hackrf_si5351c.c b/host/hackrf-tools/src/hackrf_si5351c.c index fae59409..c4fc0cdb 100644 --- a/host/hackrf-tools/src/hackrf_si5351c.c +++ b/host/hackrf-tools/src/hackrf_si5351c.c @@ -33,11 +33,12 @@ typedef int bool; static void usage() { printf("\nUsage:\n"); + printf("\t-h, --help: this help\n"); printf("\t-c, --config: print textual configuration information\n"); - printf("\t-n, --register : set register number for subsequent read/write operations\n"); + printf("\t-n, --register : set register number for read/write operations\n"); printf("\t-r, --read: read register specified by last -n argument, or all registers\n"); printf("\t-w, --write : write register specified by last -n argument with value \n"); - printf("\t-s, --device : specify a particular device by serial number\n"); + printf("\t-s, --serial : specify a particular device by serial number\n"); printf("\t-d, --device : specify a particular device by number\n"); printf("\nExamples:\n"); printf("\t -n 12 -r # reads from register 12\n"); @@ -52,6 +53,7 @@ static struct option long_options[] = { { "read", no_argument, 0, 'r' }, { "device", no_argument, 0, 'd' }, { "serial", no_argument, 0, 's' }, + { "help", no_argument, 0, 'h' }, { 0, 0, 0, 0 }, }; @@ -209,10 +211,10 @@ int main(int argc, char** argv) { int result = hackrf_init(); if( result ) { printf("hackrf_init() failed: %s (%d)\n", hackrf_error_name(result), result); - return -1; + return EXIT_FAILURE; } - while( (opt = getopt_long(argc, argv, "d:s:cn:rw:", long_options, &option_index)) != EOF ) { + while( (opt = getopt_long(argc, argv, "d:s:cn:rw:h?", long_options, &option_index)) != EOF ) { switch( opt ) { case 'n': result = parse_int(optarg, ®ister_number); @@ -220,6 +222,7 @@ int main(int argc, char** argv) { case 'w': write = true; + result = parse_int(optarg, ®ister_value); break; case 'r': @@ -237,9 +240,15 @@ int main(int argc, char** argv) { case 's': serial_number = optarg; break; + case 'h': + case '?': + usage(); + return EXIT_SUCCESS; default: + fprintf(stderr, "unknown argument '-%c %s'\n", opt, optarg); usage(); + return EXIT_FAILURE; } if( result != HACKRF_SUCCESS ) { @@ -248,6 +257,24 @@ int main(int argc, char** argv) { } } + if(write && read) { + fprintf(stderr, "Read and write options are mutually exclusive.\n"); + usage(); + return EXIT_FAILURE; + } + + if(write && dump_config) { + fprintf(stderr, "Config and write options are mutually exclusive.\n"); + usage(); + return EXIT_FAILURE; + } + + if(!(write || read || dump_config)) { + fprintf(stderr, "Specify read, write, or config option.\n"); + usage(); + return EXIT_FAILURE; + } + if(serial_number != NULL) { result = hackrf_open_by_serial(serial_number, &device); } else { @@ -259,33 +286,36 @@ int main(int argc, char** argv) { } } - if( result ) { + if(result) { printf("hackrf_open() failed: %s (%d)\n", hackrf_error_name(result), result); - return -1; + return EXIT_FAILURE; } if(write) { - result = parse_int(optarg, ®ister_value); if( result == HACKRF_SUCCESS ) { result = write_register(device, register_number, register_value); } - } else if(read) { + } + + if(read) { if( register_number == REGISTER_INVALID ) { result = dump_registers(device); } else { result = dump_register(device, register_number); } - } else if(dump_config) { + } + + if(dump_config) { dump_configuration(device); } - + result = hackrf_close(device); - if( result ) { + if(result) { printf("hackrf_close() failed: %s (%d)\n", hackrf_error_name(result), result); - return -1; + return EXIT_FAILURE; } - + hackrf_exit(); - - return 0; + + return EXIT_SUCCESS; } diff --git a/host/hackrf-tools/src/hackrf_spiflash.c b/host/hackrf-tools/src/hackrf_spiflash.c index 49cc2bf9..fabdb382 100644 --- a/host/hackrf-tools/src/hackrf_spiflash.c +++ b/host/hackrf-tools/src/hackrf_spiflash.c @@ -51,7 +51,10 @@ static struct option long_options[] = { { "length", required_argument, 0, 'l' }, { "read", required_argument, 0, 'r' }, { "write", required_argument, 0, 'w' }, + { "device", required_argument, 0, 'd' }, + { "reset", no_argument, 0, 'R' }, { "verbose", no_argument, 0, 'v' }, + { "help", no_argument, 0, 'h' }, { 0, 0, 0, 0 }, }; @@ -86,13 +89,14 @@ int parse_u32(char* s, uint32_t* const value) static void usage() { printf("Usage:\n"); + printf("\t-h, --help: this help\n"); printf("\t-a, --address : starting address (default: 0)\n"); printf("\t-l, --length : number of bytes to read (default: %d)\n", MAX_LENGTH); - printf("\t-r : Read data into file.\n"); - printf("\t-w : Write data from file.\n"); - printf("\t-d : Serial number of device, if multiple devices\n"); - printf("\t-R: Reset HackRF after other operations.\n"); - printf("\t-v: Verbose output.\n"); + printf("\t-r, --read : Read data into file.\n"); + printf("\t-w, --write : Write data from file.\n"); + printf("\t-d, --device : Serial number of device, if multiple devices\n"); + printf("\t-R, --reset: Reset HackRF after other operations.\n"); + printf("\t-v, --verbose: Verbose output.\n"); } int main(int argc, char** argv) @@ -114,8 +118,9 @@ int main(int argc, char** argv) bool write = false; bool verbose = false; bool reset = false; + uint16_t usb_api; - while ((opt = getopt_long(argc, argv, "a:l:r:w:d:vR", long_options, + while ((opt = getopt_long(argc, argv, "a:l:r:w:d:vRh?", long_options, &option_index)) != EOF) { switch (opt) { case 'a': @@ -148,9 +153,10 @@ int main(int argc, char** argv) reset = true; break; + case 'h': case '?': usage(); - return EXIT_FAILURE; + return EXIT_SUCCESS; default: fprintf(stderr, "unknown argument '-%c %s'\n", opt, optarg); @@ -304,13 +310,22 @@ int main(int argc, char** argv) } } + if (fd != NULL) { + fclose(fd); + fd = NULL; + } + if(reset) { result = hackrf_reset(device); if (result != HACKRF_SUCCESS) { - fprintf(stderr, "hackrf_reset() failed: %s (%d)\n", - hackrf_error_name(result), result); - fclose(fd); - fd = NULL; + if (result == HACKRF_ERROR_USB_API_VERSION) { + hackrf_usb_api_version_read(device, &usb_api); + fprintf(stderr, "Reset is not supported by firmware API %x.%02x\n", + (usb_api>>8)&0xFF, usb_api&0xFF); + } else { + fprintf(stderr, "hackrf_reset() failed: %s (%d)\n", + hackrf_error_name(result), result); + } return EXIT_FAILURE; } } @@ -319,16 +334,9 @@ int main(int argc, char** argv) if (result != HACKRF_SUCCESS) { fprintf(stderr, "hackrf_close() failed: %s (%d)\n", hackrf_error_name(result), result); - fclose(fd); - fd = NULL; return EXIT_FAILURE; } hackrf_exit(); - - if (fd != NULL) { - fclose(fd); - } - return EXIT_SUCCESS; } diff --git a/host/hackrf-tools/src/hackrf_sweep.c b/host/hackrf-tools/src/hackrf_sweep.c index da700fa2..0c6a81df 100644 --- a/host/hackrf-tools/src/hackrf_sweep.c +++ b/host/hackrf-tools/src/hackrf_sweep.c @@ -235,6 +235,7 @@ int rx_callback(hackrf_transfer* transfer) { static void usage() { fprintf(stderr, "Usage:\n"); + fprintf(stderr, "\t[-h] # this help\n"); fprintf(stderr, "\t[-d serial_number] # Serial number of desired HackRF.\n"); fprintf(stderr, "\t[-a amp_enable] # RX/TX RF amplifier 1=Enable, 0=Disable.\n"); fprintf(stderr, "\t[-f freq_min:freq_max # Specify minimum & maximum sweep frequencies (MHz).\n"); @@ -242,7 +243,7 @@ static void usage() { fprintf(stderr, "\t[-l gain_db] # RX LNA (IF) gain, 0-40dB, 8dB steps\n"); fprintf(stderr, "\t[-g gain_db] # RX VGA (baseband) gain, 0-62dB, 2dB steps\n"); fprintf(stderr, "\t[-x gain_db] # TX VGA (IF) gain, 0-47dB, 1dB steps\n"); - fprintf(stderr, "\t[-n num_samples] # Number of samples per frequency, 0-4294967296\n"); + fprintf(stderr, "\t[-n num_samples] # Number of samples per frequency, 16384-4294967296\n"); } static hackrf_device* device = NULL; @@ -276,7 +277,7 @@ int main(int argc, char** argv) { uint16_t frequencies[MAX_FREQ_COUNT]; uint32_t num_samples = DEFAULT_SAMPLE_COUNT; - while( (opt = getopt(argc, argv, "a:f:p:l:g:x:d:n:")) != EOF ) { + while( (opt = getopt(argc, argv, "a:f:p:l:g:x:d:n:h?")) != EOF ) { result = HACKRF_SUCCESS; switch( opt ) { @@ -325,6 +326,11 @@ int main(int argc, char** argv) { result = parse_u32(optarg, &num_samples); break; + case 'h': + case '?': + usage(); + return EXIT_SUCCESS; + default: fprintf(stderr, "unknown argument '-%c %s'\n", opt, optarg); usage(); @@ -349,6 +355,11 @@ int main(int argc, char** argv) { return EXIT_FAILURE; } + if (num_samples < 0x4000) { + fprintf(stderr, "warning: num_samples (-n) must be at least 16384\n"); + return EXIT_FAILURE; + } + if( amp ) { if( amp_enable > 1 ) { fprintf(stderr, "argument error: amp_enable shall be 0 or 1.\n"); @@ -442,7 +453,7 @@ int main(int argc, char** argv) { result |= hackrf_set_lna_gain(device, lna_gain); result |= hackrf_start_rx(device, rx_callback, NULL); if (result != HACKRF_SUCCESS) { - fprintf(stderr, "hackrf_start_?x() failed: %s (%d)\n", hackrf_error_name(result), result); + fprintf(stderr, "hackrf_start_rx() failed: %s (%d)\n", hackrf_error_name(result), result); usage(); return EXIT_FAILURE; } @@ -451,7 +462,6 @@ int main(int argc, char** argv) { if( result != HACKRF_SUCCESS ) { fprintf(stderr, "hackrf_init_sweep() failed: %s (%d)\n", hackrf_error_name(result), result); - usage(); return EXIT_FAILURE; } @@ -508,7 +518,7 @@ int main(int argc, char** argv) { result = hackrf_is_streaming(device); if (do_exit) { - fprintf(stderr, "\nUser cancel, exiting...\n"); + fprintf(stderr, "\nExiting...\n"); } else { fprintf(stderr, "\nExiting... hackrf_is_streaming() result: %s (%d)\n", hackrf_error_name(result), result); diff --git a/host/hackrf-tools/src/hackrf_transfer.c b/host/hackrf-tools/src/hackrf_transfer.c index a36166c6..88221716 100644 --- a/host/hackrf-tools/src/hackrf_transfer.c +++ b/host/hackrf-tools/src/hackrf_transfer.c @@ -357,6 +357,8 @@ bool repeat = false; bool crystal_correct = false; uint32_t crystal_correct_ppm ; +int requested_mode_count = 0; + int rx_callback(hackrf_transfer* transfer) { size_t bytes_to_write; size_t bytes_written; @@ -469,6 +471,7 @@ int tx_callback(hackrf_transfer* transfer) { static void usage() { printf("Usage:\n"); + printf("\t-h # this help\n"); printf("\t[-d serial_number] # Serial number of desired HackRF.\n"); printf("\t-r # Receive data into file (use '-' for stdout).\n"); printf("\t-t # Transmit data from file (use '-' for stdin).\n"); @@ -544,7 +547,7 @@ int main(int argc, char** argv) { float time_diff; unsigned int lna_gain=8, vga_gain=20, txvga_gain=0; - while( (opt = getopt(argc, argv, "Hwr:t:f:i:o:m:a:p:s:n:b:l:g:x:c:d:C:RS:")) != EOF ) + while( (opt = getopt(argc, argv, "Hwr:t:f:i:o:m:a:p:s:n:b:l:g:x:c:d:C:RS:h?")) != EOF ) { result = HACKRF_SUCCESS; switch( opt ) @@ -554,15 +557,18 @@ int main(int argc, char** argv) { break; case 'w': receive_wav = true; + requested_mode_count++; break; case 'r': receive = true; + requested_mode_count++; path = optarg; break; case 't': transmit = true; + requested_mode_count++; path = optarg; break; @@ -659,8 +665,8 @@ int main(int argc, char** argv) { break; case 'c': - transmit = true; signalsource = true; + requested_mode_count++; result = parse_u32(optarg, &litude); break; @@ -673,9 +679,10 @@ int main(int argc, char** argv) { result = parse_u32(optarg, &crystal_correct_ppm); break; + case 'h': case '?': usage(); - return EXIT_FAILURE; + return EXIT_SUCCESS; default: fprintf(stderr, "unknown argument '-%c %s'\n", opt, optarg); @@ -818,33 +825,22 @@ int main(int argc, char** argv) { } } - if( (transmit == false) && (receive == receive_wav) ) - { - fprintf(stderr, "receive -r and receive_wav -w options are mutually exclusive\n"); + if(requested_mode_count > 1) { + fprintf(stderr, "specify only one of: -t, -c, -r, -w\n"); usage(); return EXIT_FAILURE; } - - if( receive_wav == false ) - { - if( transmit == receive ) - { - if( transmit == true ) - { - fprintf(stderr, "receive -r and transmit -t options are mutually exclusive\n"); - } else - { - fprintf(stderr, "specify either transmit -t or receive -r or receive_wav -w option\n"); - } - usage(); - return EXIT_FAILURE; - } + + if(requested_mode_count < 1) { + fprintf(stderr, "specify one of: -t, -c, -r, -w\n"); + usage(); + return EXIT_FAILURE; } - + if( receive ) { transceiver_mode = TRANSCEIVER_MODE_RX; } - + if( transmit ) { transceiver_mode = TRANSCEIVER_MODE_TX; } @@ -852,7 +848,7 @@ int main(int argc, char** argv) { if (signalsource) { transceiver_mode = TRANSCEIVER_MODE_SS; if (amplitude >127) { - fprintf(stderr, "argument error: amplitude shall be in between 0 and 128.\n"); + fprintf(stderr, "argument error: amplitude shall be in between 0 and 127.\n"); usage(); return EXIT_FAILURE; } @@ -965,12 +961,10 @@ int main(int argc, char** argv) { } } - fprintf(stderr, "call hackrf_set_hw_sync_mode(%d)\n", - hw_sync); + fprintf(stderr, "call hackrf_set_hw_sync_mode(%d)\n", hw_sync); result = hackrf_set_hw_sync_mode(device, hw_sync ? HW_SYNC_MODE_ON : HW_SYNC_MODE_OFF); if( result != HACKRF_SUCCESS ) { fprintf(stderr, "hackrf_set_hw_sync_mode() failed: %s (%d)\n", hackrf_error_name(result), result); - usage(); return EXIT_FAILURE; } @@ -1093,33 +1087,30 @@ int main(int argc, char** argv) { } } } - + result = hackrf_is_streaming(device); if (do_exit) { - fprintf(stderr, "\nUser cancel, exiting...\n"); + fprintf(stderr, "\nExiting...\n"); } else { fprintf(stderr, "\nExiting... hackrf_is_streaming() result: %s (%d)\n", hackrf_error_name(result), result); } - + gettimeofday(&t_end, NULL); time_diff = TimevalDiff(&t_end, &t_start); fprintf(stderr, "Total time: %5.5f s\n", time_diff); - - if(device != NULL) - { - if( receive ) - { + + if(device != NULL) { + if(receive || receive_wav) { result = hackrf_stop_rx(device); if( result != HACKRF_SUCCESS ) { fprintf(stderr, "hackrf_stop_rx() failed: %s (%d)\n", hackrf_error_name(result), result); - }else { + } else { fprintf(stderr, "hackrf_stop_rx() done\n"); } } - - if( transmit ) - { + + if(transmit || signalsource) { result = hackrf_stop_tx(device); if( result != HACKRF_SUCCESS ) { fprintf(stderr, "hackrf_stop_tx() failed: %s (%d)\n", hackrf_error_name(result), result); @@ -1127,19 +1118,18 @@ int main(int argc, char** argv) { fprintf(stderr, "hackrf_stop_tx() done\n"); } } - + result = hackrf_close(device); - if( result != HACKRF_SUCCESS ) - { + if(result != HACKRF_SUCCESS) { fprintf(stderr, "hackrf_close() failed: %s (%d)\n", hackrf_error_name(result), result); - }else { + } else { fprintf(stderr, "hackrf_close() done\n"); } - + hackrf_exit(); fprintf(stderr, "hackrf_exit() done\n"); } - + if(fd != NULL) { if( receive_wav ) diff --git a/host/libhackrf/src/hackrf.c b/host/libhackrf/src/hackrf.c index 30c604f2..ba3e5e0c 100644 --- a/host/libhackrf/src/hackrf.c +++ b/host/libhackrf/src/hackrf.c @@ -24,7 +24,7 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSI #include "hackrf.h" #include - +#include #include #ifdef _WIN32 @@ -98,17 +98,19 @@ typedef enum { HACKRF_HW_SYNC_MODE_ON = 1, } hackrf_hw_sync_mode; +#define TRANSFER_COUNT 4 +#define TRANSFER_BUFFER_SIZE 262144 + struct hackrf_device { libusb_device_handle* usb_device; struct libusb_transfer** transfers; hackrf_sample_block_cb_fn callback; volatile bool transfer_thread_started; /* volatile shared between threads (read only) */ pthread_t transfer_thread; - uint32_t transfer_count; - uint32_t buffer_size; volatile bool streaming; /* volatile shared between threads (read only) */ void* rx_ctx; void* tx_ctx; + unsigned char buffer[TRANSFER_COUNT * TRANSFER_BUFFER_SIZE]; }; typedef struct { @@ -155,7 +157,7 @@ static int cancel_transfers(hackrf_device* device) if( device->transfers != NULL ) { - for(transfer_index=0; transfer_indextransfer_count; transfer_index++) + for(transfer_index=0; transfer_indextransfers[transfer_index] != NULL ) { @@ -175,7 +177,7 @@ static int free_transfers(hackrf_device* device) if( device->transfers != NULL ) { // libusb_close() should free all transfers referenced from this array. - for(transfer_index=0; transfer_indextransfer_count; transfer_index++) + for(transfer_index=0; transfer_indextransfers[transfer_index] != NULL ) { @@ -194,13 +196,13 @@ static int allocate_transfers(hackrf_device* const device) if( device->transfers == NULL ) { uint32_t transfer_index; - device->transfers = (struct libusb_transfer**) calloc(device->transfer_count, sizeof(struct libusb_transfer)); + device->transfers = (struct libusb_transfer**) calloc(TRANSFER_COUNT, sizeof(struct libusb_transfer)); if( device->transfers == NULL ) { return HACKRF_ERROR_NO_MEM; } - for(transfer_index=0; transfer_indextransfer_count; transfer_index++) + for(transfer_index=0; transfer_indextransfers[transfer_index] = libusb_alloc_transfer(0); if( device->transfers[transfer_index] == NULL ) @@ -212,8 +214,8 @@ static int allocate_transfers(hackrf_device* const device) device->transfers[transfer_index], device->usb_device, 0, - (unsigned char*)malloc(device->buffer_size), - device->buffer_size, + &device->buffer[transfer_index * TRANSFER_BUFFER_SIZE], + TRANSFER_BUFFER_SIZE, NULL, device, 0 @@ -239,7 +241,7 @@ static int prepare_transfers( uint32_t transfer_index; if( device->transfers != NULL ) { - for(transfer_index=0; transfer_indextransfer_count; transfer_index++) + for(transfer_index=0; transfer_indextransfers[transfer_index]->endpoint = endpoint_address; device->transfers[transfer_index]->callback = callback; @@ -355,9 +357,6 @@ int ADDCALL hackrf_exit(void) return HACKRF_SUCCESS; } -#include -#include - hackrf_device_list_t* ADDCALL hackrf_device_list() { ssize_t i; @@ -442,8 +441,6 @@ libusb_device_handle* hackrf_open_usb(const char* const desired_serial_number) char serial_number[64]; int serial_number_length; - printf("Number of USB devices: %ld\n", list_length); - if( desired_serial_number ) { /* If a shorter serial number is specified, only match against the suffix. * Should probably complain if the match is not unique, currently doesn't. @@ -461,7 +458,6 @@ libusb_device_handle* hackrf_open_usb(const char* const desired_serial_number) if((device_descriptor.idProduct == hackrf_one_usb_pid) || (device_descriptor.idProduct == hackrf_jawbreaker_usb_pid) || (device_descriptor.idProduct == rad1o_usb_pid)) { - printf("USB device %4x:%4x:", device_descriptor.idVendor, device_descriptor.idProduct); if( desired_serial_number != NULL ) { const uint_fast8_t serial_descriptor_index = device_descriptor.iSerialNumber; @@ -473,23 +469,18 @@ libusb_device_handle* hackrf_open_usb(const char* const desired_serial_number) serial_number_length = libusb_get_string_descriptor_ascii(usb_device, serial_descriptor_index, (unsigned char*)serial_number, sizeof(serial_number)); if( serial_number_length == 32 ) { serial_number[32] = 0; - printf(" %s", serial_number); if( strncmp(serial_number + 32-match_len, desired_serial_number, match_len) == 0 ) { - printf(" match\n"); break; } else { - printf(" skip\n"); libusb_close(usb_device); usb_device = NULL; } } else { - printf(" wrong length of serial number: %d\n", serial_number_length); libusb_close(usb_device); usb_device = NULL; } } } else { - printf(" default\n"); libusb_open(devices[i], &usb_device); break; } @@ -537,12 +528,6 @@ static int hackrf_open_setup(libusb_device_handle* usb_device, hackrf_device** d lib_device->transfers = NULL; lib_device->callback = NULL; lib_device->transfer_thread_started = false; - /* - lib_device->transfer_count = 1024; - lib_device->buffer_size = 16384; - */ - lib_device->transfer_count = 4; - lib_device->buffer_size = 262144; /* 1048576; */ lib_device->streaming = false; do_exit = false; @@ -1012,6 +997,27 @@ int ADDCALL hackrf_version_string_read(hackrf_device* device, char* version, } } +extern ADDAPI int ADDCALL hackrf_usb_api_version_read(hackrf_device* device, + uint16_t* version) +{ + int result; + libusb_device* dev; + struct libusb_device_descriptor desc; + dev = libusb_get_device(device->usb_device); + result = libusb_get_device_descriptor(dev, &desc); + if (result < 0) + return HACKRF_ERROR_LIBUSB; + + *version = desc.bcdDevice; + return HACKRF_SUCCESS; +} + +#define USB_API_REQUIRED(device, version) \ +uint16_t usb_version = 0; \ +hackrf_usb_api_version_read(device, &usb_version); \ +if(usb_version < version) \ + return HACKRF_ERROR_USB_API_VERSION; + typedef struct { uint32_t freq_mhz; /* From 0 to 6000+MHz */ uint32_t freq_hz; /* From 0 to 999999Hz */ @@ -1577,26 +1583,6 @@ int ADDCALL hackrf_close(hackrf_device* device) return result1; } -int ADDCALL hackrf_set_hw_sync_mode(hackrf_device* device, const uint8_t value) { - int result = libusb_control_transfer( - device->usb_device, - LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, - HACKRF_VENDOR_REQUEST_SET_HW_SYNC_MODE, - value, - 0, - NULL, - 0, - 0 - ); - - if( result != 0 ) - { - return HACKRF_ERROR_LIBUSB; - } else { - return HACKRF_SUCCESS; - } -} - const char* ADDCALL hackrf_error_name(enum hackrf_error errcode) { switch(errcode) @@ -1608,37 +1594,40 @@ const char* ADDCALL hackrf_error_name(enum hackrf_error errcode) return "HACKRF_TRUE"; case HACKRF_ERROR_INVALID_PARAM: - return "HACKRF_ERROR_INVALID_PARAM"; + return "invalid parameter(s)"; case HACKRF_ERROR_NOT_FOUND: - return "HACKRF_ERROR_NOT_FOUND"; + return "HackRF not found"; case HACKRF_ERROR_BUSY: - return "HACKRF_ERROR_BUSY"; + return "HackRF busy"; case HACKRF_ERROR_NO_MEM: - return "HACKRF_ERROR_NO_MEM"; + return "insufficient memory"; case HACKRF_ERROR_LIBUSB: - return "HACKRF_ERROR_LIBUSB"; + return "USB error"; case HACKRF_ERROR_THREAD: - return "HACKRF_ERROR_THREAD"; + return "transfer thread error"; case HACKRF_ERROR_STREAMING_THREAD_ERR: - return "HACKRF_ERROR_STREAMING_THREAD_ERR"; + return "streaming thread encountered an error"; case HACKRF_ERROR_STREAMING_STOPPED: - return "HACKRF_ERROR_STREAMING_STOPPED"; + return "streaming stopped"; case HACKRF_ERROR_STREAMING_EXIT_CALLED: - return "HACKRF_ERROR_STREAMING_EXIT_CALLED"; + return "streaming terminated"; + + case HACKRF_ERROR_USB_API_VERSION: + return "feature not supported by installed firmware"; case HACKRF_ERROR_OTHER: - return "HACKRF_ERROR_OTHER"; + return "unspecified error"; default: - return "HACKRF unknown error"; + return "unknown error code"; } } @@ -1744,9 +1733,33 @@ uint32_t ADDCALL hackrf_compute_baseband_filter_bw(const uint32_t bandwidth_hz) return p->bandwidth_hz; } +/* All features below require USB API version 0x1002 or higher) */ + +int ADDCALL hackrf_set_hw_sync_mode(hackrf_device* device, const uint8_t value) { + USB_API_REQUIRED(device, 0x0102) + int result = libusb_control_transfer( + device->usb_device, + LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, + HACKRF_VENDOR_REQUEST_SET_HW_SYNC_MODE, + value, + 0, + NULL, + 0, + 0 + ); + + if( result != 0 ) + { + return HACKRF_ERROR_LIBUSB; + } else { + return HACKRF_SUCCESS; + } +} + /* Initialise sweep mode with alist of frequencies and dwell time in samples */ int ADDCALL hackrf_init_sweep(hackrf_device* device, uint16_t* frequency_list, int length, uint32_t dwell_time) { + USB_API_REQUIRED(device, 0x0102) int result, i; int size = length * sizeof(frequency_list[0]); @@ -1776,6 +1789,7 @@ int ADDCALL hackrf_init_sweep(hackrf_device* device, uint16_t* frequency_list, i */ int ADDCALL hackrf_get_operacake_boards(hackrf_device* device, uint8_t* boards) { + USB_API_REQUIRED(device, 0x0102) int result; result = libusb_control_transfer( device->usb_device, @@ -1802,6 +1816,7 @@ int ADDCALL hackrf_set_operacake_ports(hackrf_device* device, uint8_t port_a, uint8_t port_b) { + USB_API_REQUIRED(device, 0x0102) int result; /* Error checking */ if((port_a > OPERACAKE_PB4) || (port_b > OPERACAKE_PB4)) { @@ -1831,6 +1846,7 @@ int ADDCALL hackrf_set_operacake_ports(hackrf_device* device, } int ADDCALL hackrf_reset(hackrf_device* device) { + USB_API_REQUIRED(device, 0x0102) int result = libusb_control_transfer( device->usb_device, LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, diff --git a/host/libhackrf/src/hackrf.h b/host/libhackrf/src/hackrf.h index 06826aad..d1a57c4d 100644 --- a/host/libhackrf/src/hackrf.h +++ b/host/libhackrf/src/hackrf.h @@ -59,6 +59,7 @@ enum hackrf_error { HACKRF_ERROR_STREAMING_THREAD_ERR = -1002, HACKRF_ERROR_STREAMING_STOPPED = -1003, HACKRF_ERROR_STREAMING_EXIT_CALLED = -1004, + HACKRF_ERROR_USB_API_VERSION = -1005, HACKRF_ERROR_OTHER = -9999, }; @@ -170,6 +171,7 @@ extern ADDAPI int ADDCALL hackrf_cpld_write(hackrf_device* device, extern ADDAPI int ADDCALL hackrf_board_id_read(hackrf_device* device, uint8_t* value); extern ADDAPI int ADDCALL hackrf_version_string_read(hackrf_device* device, char* version, uint8_t length); +extern ADDAPI int ADDCALL hackrf_usb_api_version_read(hackrf_device* device, uint16_t* version); extern ADDAPI int ADDCALL hackrf_set_freq(hackrf_device* device, const uint64_t freq_hz); extern ADDAPI int ADDCALL hackrf_set_freq_explicit(hackrf_device* device, @@ -198,9 +200,6 @@ extern ADDAPI int ADDCALL hackrf_set_txvga_gain(hackrf_device* device, uint32_t /* antenna port power control */ extern ADDAPI int ADDCALL hackrf_set_antenna_enable(hackrf_device* device, const uint8_t value); -/* set hardware sync mode */ -extern ADDAPI int ADDCALL hackrf_set_hw_sync_mode(hackrf_device* device, const uint8_t value); - extern ADDAPI const char* ADDCALL hackrf_error_name(enum hackrf_error errcode); extern ADDAPI const char* ADDCALL hackrf_board_id_name(enum hackrf_board_id board_id); extern ADDAPI const char* ADDCALL hackrf_usb_board_id_name(enum hackrf_usb_board_id usb_board_id); @@ -210,6 +209,12 @@ extern ADDAPI const char* ADDCALL hackrf_filter_path_name(const enum rf_path_fil extern ADDAPI uint32_t ADDCALL hackrf_compute_baseband_filter_bw_round_down_lt(const uint32_t bandwidth_hz); /* Compute best default value depending on sample rate (auto filter) */ extern ADDAPI uint32_t ADDCALL hackrf_compute_baseband_filter_bw(const uint32_t bandwidth_hz); + +/* All features below require USB API version 0x1002 or higher) */ + +/* set hardware sync mode */ +extern ADDAPI int ADDCALL hackrf_set_hw_sync_mode(hackrf_device* device, const uint8_t value); + /* Start scan mode */ extern ADDAPI int ADDCALL hackrf_init_sweep(hackrf_device* device, uint16_t* frequency_list, diff --git a/issue_template.md b/issue_template.md new file mode 100644 index 00000000..06f0c9ee --- /dev/null +++ b/issue_template.md @@ -0,0 +1,23 @@ +### Steps to reproduce +1. +2. +3. + +### Expected behaviour +Tell us what you expect should happen + +### Actual behaviour +Tell us what happens instead + +### Version information +**Operating system**: + +**hackrf_info output:** + +If you are reporting a problem that involves third party software +(GNU Radio, Gqrx, etc), please report the version here. + +### Output +``` +Insert any commandline or build output here +```