From 3302ca3146cdc301b41d0a2f32139b75f05581d7 Mon Sep 17 00:00:00 2001 From: schneider42 Date: Fri, 3 Feb 2017 16:36:32 +0100 Subject: [PATCH 01/59] fix(readme): Use correct DFU filename --- firmware/README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/README b/firmware/README index 07fb628d..94cccc9f 100644 --- a/firmware/README +++ b/firmware/README @@ -45,4 +45,4 @@ after the 3V3 LED illuminates. A .dfu file is built by default when building firmware. Alternatively you can load a known good .dfu file from a release package with: -$ dfu-util --device 1fc9:000c --alt 0 --download hackrf_usb_ram.dfu +$ dfu-util --device 1fc9:000c --alt 0 --download hackrf_usb.dfu From 55d7e7f2d27367670a7ef254434b42f0ab592b5a Mon Sep 17 00:00:00 2001 From: Dominic Spill Date: Fri, 3 Feb 2017 10:08:41 -0700 Subject: [PATCH 02/59] Standardize device selection options in hackrf-tools Fixes issue #318 --- host/hackrf-tools/src/hackrf_operacake.c | 23 ++++++----------------- host/hackrf-tools/src/hackrf_si5351c.c | 12 ++++++------ 2 files changed, 12 insertions(+), 23 deletions(-) diff --git a/host/hackrf-tools/src/hackrf_operacake.c b/host/hackrf-tools/src/hackrf_operacake.c index 91e1e0d2..5162d060 100644 --- a/host/hackrf-tools/src/hackrf_operacake.c +++ b/host/hackrf-tools/src/hackrf_operacake.c @@ -34,7 +34,6 @@ 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"); @@ -44,7 +43,6 @@ static void usage() { 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' }, @@ -65,7 +63,6 @@ int parse_int(char* const s, uint16_t* const value) { int main(int argc, char** argv) { int opt; const char* serial_number = NULL; - int device_index = 0; int operacake_address = 0; int port_a = 0; int port_b = 0; @@ -83,13 +80,9 @@ int main(int argc, char** argv) { return -1; } - while( (opt = getopt_long(argc, argv, "d:s:o:a:b:lh?", long_options, &option_index)) != EOF ) { + while( (opt = getopt_long(argc, argv, "d:o:a:b:lh?", long_options, &option_index)) != EOF ) { switch( opt ) { case 'd': - device_index = atoi(optarg); - break; - - case 's': serial_number = optarg; break; @@ -132,15 +125,11 @@ int main(int argc, char** argv) { return EXIT_FAILURE; } - if(serial_number != NULL) { - result = hackrf_open_by_serial(serial_number, &device); - } else { - hackrf_device_list_t* device_list = hackrf_device_list(); - if(device_list->devicecount <= 0) { - result = HACKRF_ERROR_NOT_FOUND; - } else { - result = hackrf_device_list_open(device_list, device_index, &device); - } + result = hackrf_open_by_serial(serial_number, &device); + if (result != HACKRF_SUCCESS) { + fprintf(stderr, "hackrf_open() failed: %s (%d)\n", + hackrf_error_name(result), result); + return EXIT_FAILURE; } if( result ) { diff --git a/host/hackrf-tools/src/hackrf_si5351c.c b/host/hackrf-tools/src/hackrf_si5351c.c index c4fc0cdb..7c8712c4 100644 --- a/host/hackrf-tools/src/hackrf_si5351c.c +++ b/host/hackrf-tools/src/hackrf_si5351c.c @@ -38,8 +38,8 @@ static void usage() { 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, --serial : specify a particular device by serial number\n"); - printf("\t-d, --device : specify a particular device by number\n"); + printf("\t-d, --device : specify a particular device by serial number\n"); + printf("\t-D, --device-idx : specify a particular device by number\n"); printf("\nExamples:\n"); printf("\t -n 12 -r # reads from register 12\n"); printf("\t -r # reads all registers\n"); @@ -52,7 +52,7 @@ static struct option long_options[] = { { "write", required_argument, 0, 'w' }, { "read", no_argument, 0, 'r' }, { "device", no_argument, 0, 'd' }, - { "serial", no_argument, 0, 's' }, + { "device-idx", no_argument, 0, 'D' }, { "help", no_argument, 0, 'h' }, { 0, 0, 0, 0 }, }; @@ -214,7 +214,7 @@ int main(int argc, char** argv) { return EXIT_FAILURE; } - while( (opt = getopt_long(argc, argv, "d:s:cn:rw:h?", long_options, &option_index)) != EOF ) { + while( (opt = getopt_long(argc, argv, "d:D:cn:rw:h?", long_options, &option_index)) != EOF ) { switch( opt ) { case 'n': result = parse_int(optarg, ®ister_number); @@ -233,11 +233,11 @@ int main(int argc, char** argv) { dump_config = true; break; - case 'd': + case 'D': device_index = atoi(optarg); break; - case 's': + case 'd': serial_number = optarg; break; case 'h': From feeb7a9c95e3bdfb416305b1c70e232fdf5b2fc4 Mon Sep 17 00:00:00 2001 From: Dominic Spill Date: Fri, 3 Feb 2017 10:20:23 -0700 Subject: [PATCH 03/59] Add selection by device serial number to rffc5071 and max2837 tools --- host/hackrf-tools/src/hackrf_max2837.c | 11 +++++++++-- host/hackrf-tools/src/hackrf_operacake.c | 5 ----- host/hackrf-tools/src/hackrf_rffc5071.c | 10 ++++++++-- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/host/hackrf-tools/src/hackrf_max2837.c b/host/hackrf-tools/src/hackrf_max2837.c index d09a7557..f52ca9e1 100644 --- a/host/hackrf-tools/src/hackrf_max2837.c +++ b/host/hackrf-tools/src/hackrf_max2837.c @@ -38,6 +38,7 @@ static void usage() { 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-d, --device : specify a particular device by serial number\n"); printf("\nExamples:\n"); printf("\t -n 12 -r # reads from register 12\n"); printf("\t -r # reads all registers\n"); @@ -48,6 +49,7 @@ static struct option long_options[] = { { "register", required_argument, 0, 'n' }, { "write", required_argument, 0, 'w' }, { "read", no_argument, 0, 'r' }, + { "device", no_argument, 0, 'd' }, { "help", no_argument, 0, 'h' }, { 0, 0, 0, 0 }, }; @@ -133,6 +135,7 @@ int main(int argc, char** argv) { int option_index = 0; bool read = false; bool write = false; + const char* serial_number = NULL; int result = hackrf_init(); if( result ) { @@ -140,7 +143,7 @@ int main(int argc, char** argv) { return EXIT_FAILURE; } - while( (opt = getopt_long(argc, argv, "n:rw:h?", long_options, &option_index)) != EOF ) { + while( (opt = getopt_long(argc, argv, "n:rw:d:h?", long_options, &option_index)) != EOF ) { switch( opt ) { case 'n': result = parse_int(optarg, ®ister_number); @@ -155,6 +158,10 @@ int main(int argc, char** argv) { read = true; break; + case 'd': + serial_number = optarg; + break; + case 'h': case '?': usage(); @@ -184,7 +191,7 @@ int main(int argc, char** argv) { return EXIT_FAILURE; } - result = hackrf_open(&device); + result = hackrf_open_by_serial(serial_number, &device); if(result) { printf("hackrf_open() failed: %s (%d)\n", hackrf_error_name(result), result); return EXIT_FAILURE; diff --git a/host/hackrf-tools/src/hackrf_operacake.c b/host/hackrf-tools/src/hackrf_operacake.c index 5162d060..649f9902 100644 --- a/host/hackrf-tools/src/hackrf_operacake.c +++ b/host/hackrf-tools/src/hackrf_operacake.c @@ -132,11 +132,6 @@ int main(int argc, char** argv) { return EXIT_FAILURE; } - if( result ) { - printf("hackrf_open() failed: %s (%d)\n", hackrf_error_name(result), result); - return -1; - } - if(list) { result = hackrf_get_operacake_boards(device, operacakes); if (result != HACKRF_SUCCESS) { diff --git a/host/hackrf-tools/src/hackrf_rffc5071.c b/host/hackrf-tools/src/hackrf_rffc5071.c index 11285d83..867bc379 100644 --- a/host/hackrf-tools/src/hackrf_rffc5071.c +++ b/host/hackrf-tools/src/hackrf_rffc5071.c @@ -39,6 +39,7 @@ static void usage() { 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-d, --device : specify a particular device by serial number\n"); printf("\nExamples:\n"); printf("\t -n 12 -r # reads from register 12\n"); printf("\t -r # reads all registers\n"); @@ -49,6 +50,7 @@ static struct option long_options[] = { { "register", required_argument, 0, 'n' }, { "write", required_argument, 0, 'w' }, { "read", no_argument, 0, 'r' }, + { "device", no_argument, 0, 'd' }, { "help", no_argument, 0, 'h' }, { 0, 0, 0, 0 }, }; @@ -134,6 +136,7 @@ int main(int argc, char** argv) { int option_index = 0; bool read = false; bool write = false; + const char* serial_number = NULL; int result = hackrf_init(); if( result ) { @@ -141,7 +144,7 @@ int main(int argc, char** argv) { return EXIT_FAILURE; } - while( (opt = getopt_long(argc, argv, "n:rw:h?", long_options, &option_index)) != EOF ) { + while( (opt = getopt_long(argc, argv, "n:rw:d:h?", long_options, &option_index)) != EOF ) { switch( opt ) { case 'n': result = parse_int(optarg, ®ister_number); @@ -153,6 +156,9 @@ int main(int argc, char** argv) { case 'r': read = true; break; + case 'd': + serial_number = optarg; + break; case 'h': case '?': usage(); @@ -182,7 +188,7 @@ int main(int argc, char** argv) { return EXIT_FAILURE; } - result = hackrf_open(&device); + result = hackrf_open_by_serial(serial_number, &device); if(result) { printf("hackrf_open() failed: %s (%d)\n", hackrf_error_name(result), result); return EXIT_FAILURE; From 296117f3bb928b4ee327bbf99c895f021ab48775 Mon Sep 17 00:00:00 2001 From: Michael Ossmann Date: Fri, 3 Feb 2017 11:58:26 -0700 Subject: [PATCH 04/59] removed unused TX options from hackrf_sweep --- host/hackrf-tools/src/hackrf_sweep.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/host/hackrf-tools/src/hackrf_sweep.c b/host/hackrf-tools/src/hackrf_sweep.c index 0c6a81df..dca716cf 100644 --- a/host/hackrf-tools/src/hackrf_sweep.c +++ b/host/hackrf-tools/src/hackrf_sweep.c @@ -237,12 +237,11 @@ 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[-a amp_enable] # RX RF amplifier 1=Enable, 0=Disable.\n"); fprintf(stderr, "\t[-f freq_min:freq_max # Specify minimum & maximum sweep frequencies (MHz).\n"); fprintf(stderr, "\t[-p antenna_enable] # Antenna port power, 1=Enable, 0=Disable.\n"); 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, 16384-4294967296\n"); } @@ -273,11 +272,11 @@ int main(int argc, char** argv) { int exit_code = EXIT_SUCCESS; struct timeval t_end; float time_diff; - unsigned int lna_gain=16, vga_gain=20, txvga_gain=0; + unsigned int lna_gain=16, vga_gain=20; 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:h?")) != EOF ) { + while( (opt = getopt(argc, argv, "a:f:p:l:g:d:n:h?")) != EOF ) { result = HACKRF_SUCCESS; switch( opt ) { @@ -318,10 +317,6 @@ int main(int argc, char** argv) { result = parse_u32(optarg, &vga_gain); break; - case 'x': - result = parse_u32(optarg, &txvga_gain); - break; - case 'n': result = parse_u32(optarg, &num_samples); break; From 3c468a7a0f6d8fe9d9ffb706a71a50ed7da9be29 Mon Sep 17 00:00:00 2001 From: Dominic Spill Date: Fri, 3 Feb 2017 12:05:10 -0700 Subject: [PATCH 05/59] Report libusb error messages where possible for USB errors --- host/libhackrf/src/hackrf.c | 48 ++++++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/host/libhackrf/src/hackrf.c b/host/libhackrf/src/hackrf.c index ba3e5e0c..c858f66d 100644 --- a/host/libhackrf/src/hackrf.c +++ b/host/libhackrf/src/hackrf.c @@ -145,6 +145,7 @@ static const uint16_t hackrf_one_usb_pid = 0x6089; static const uint16_t rad1o_usb_pid = 0xcc15; static libusb_context* g_libusb_context = NULL; +int last_libusb_error = LIBUSB_SUCCESS; static void request_exit(void) { @@ -249,6 +250,7 @@ static int prepare_transfers( error = libusb_submit_transfer(device->transfers[transfer_index]); if( error != 0 ) { + last_libusb_error = error; return HACKRF_ERROR_LIBUSB; } } @@ -269,6 +271,7 @@ static int detach_kernel_drivers(libusb_device_handle* usb_device_handle) result = libusb_get_active_config_descriptor(dev, &config); if( result < 0 ) { + last_libusb_error = result; return HACKRF_ERROR_LIBUSB; } @@ -282,11 +285,13 @@ static int detach_kernel_drivers(libusb_device_handle* usb_device_handle) if( result == LIBUSB_ERROR_NOT_SUPPORTED ) { return 0; } + last_libusb_error = result; return HACKRF_ERROR_LIBUSB; } else if( result == 1 ) { result = libusb_detach_kernel_driver(usb_device_handle, i); if( result != 0 ) { + last_libusb_error = result; return HACKRF_ERROR_LIBUSB; } } @@ -300,6 +305,7 @@ static int set_hackrf_configuration(libusb_device_handle* usb_device, int config result = libusb_get_configuration(usb_device, &curr_config); if( result != 0 ) { + last_libusb_error = result; return HACKRF_ERROR_LIBUSB; } @@ -313,6 +319,7 @@ static int set_hackrf_configuration(libusb_device_handle* usb_device, int config result = libusb_set_configuration(usb_device, config); if( result != 0 ) { + last_libusb_error = result; return HACKRF_ERROR_LIBUSB; } } @@ -340,6 +347,7 @@ int ADDCALL hackrf_init(void) libusb_error = libusb_init(&g_libusb_context); if( libusb_error != 0 ) { + last_libusb_error = libusb_error; return HACKRF_ERROR_LIBUSB; } else { return HACKRF_SUCCESS; @@ -511,6 +519,7 @@ static int hackrf_open_setup(libusb_device_handle* usb_device, hackrf_device** d result = libusb_claim_interface(usb_device, 0); if( result != LIBUSB_SUCCESS ) { + last_libusb_error = result; libusb_close(usb_device); return HACKRF_ERROR_LIBUSB; } @@ -601,7 +610,7 @@ int ADDCALL hackrf_open_by_serial(const char* const desired_serial_number, hackr int ADDCALL hackrf_device_list_open(hackrf_device_list_t *list, int idx, hackrf_device** device) { libusb_device_handle* usb_device; - int i; + int i, result; if( device == NULL || list == NULL || idx < 0 || idx >= list->devicecount ) { @@ -610,8 +619,10 @@ int ADDCALL hackrf_device_list_open(hackrf_device_list_t *list, int idx, hackrf_ i = list->usb_device_index[idx]; - if( libusb_open(list->usb_devices[i], &usb_device) != 0 ) { + result = libusb_open(list->usb_devices[i], &usb_device); + if(result != 0) { usb_device = NULL; + last_libusb_error = result; return HACKRF_ERROR_LIBUSB; } @@ -634,6 +645,7 @@ int ADDCALL hackrf_set_transceiver_mode(hackrf_device* device, hackrf_transceive if( result != 0 ) { + last_libusb_error = result; return HACKRF_ERROR_LIBUSB; } else { return HACKRF_SUCCESS; @@ -662,6 +674,7 @@ int ADDCALL hackrf_max2837_read(hackrf_device* device, uint8_t register_number, if( result < 2 ) { + last_libusb_error = result; return HACKRF_ERROR_LIBUSB; } else { return HACKRF_SUCCESS; @@ -694,6 +707,7 @@ int ADDCALL hackrf_max2837_write(hackrf_device* device, uint8_t register_number, if( result != 0 ) { + last_libusb_error = result; return HACKRF_ERROR_LIBUSB; } else { return HACKRF_SUCCESS; @@ -724,6 +738,7 @@ int ADDCALL hackrf_si5351c_read(hackrf_device* device, uint16_t register_number, if( result < 1 ) { + last_libusb_error = result; return HACKRF_ERROR_LIBUSB; } else { *value = temp_value; @@ -756,6 +771,7 @@ int ADDCALL hackrf_si5351c_write(hackrf_device* device, uint16_t register_number if( result != 0 ) { + last_libusb_error = result; return HACKRF_ERROR_LIBUSB; } else { return HACKRF_SUCCESS; @@ -778,6 +794,7 @@ int ADDCALL hackrf_set_baseband_filter_bandwidth(hackrf_device* device, const ui if( result != 0 ) { + last_libusb_error = result; return HACKRF_ERROR_LIBUSB; } else { return HACKRF_SUCCESS; @@ -807,6 +824,7 @@ int ADDCALL hackrf_rffc5071_read(hackrf_device* device, uint8_t register_number, if( result < 2 ) { + last_libusb_error = result; return HACKRF_ERROR_LIBUSB; } else { return HACKRF_SUCCESS; @@ -835,6 +853,7 @@ int ADDCALL hackrf_rffc5071_write(hackrf_device* device, uint8_t register_number if( result != 0 ) { + last_libusb_error = result; return HACKRF_ERROR_LIBUSB; } else { return HACKRF_SUCCESS; @@ -857,6 +876,7 @@ int ADDCALL hackrf_spiflash_erase(hackrf_device* device) if (result != 0) { + last_libusb_error = result; return HACKRF_ERROR_LIBUSB; } else { return HACKRF_SUCCESS; @@ -886,6 +906,7 @@ int ADDCALL hackrf_spiflash_write(hackrf_device* device, const uint32_t address, if (result < length) { + last_libusb_error = result; return HACKRF_ERROR_LIBUSB; } else { return HACKRF_SUCCESS; @@ -915,6 +936,7 @@ int ADDCALL hackrf_spiflash_read(hackrf_device* device, const uint32_t address, if (result < length) { + last_libusb_error = result; return HACKRF_ERROR_LIBUSB; } else { return HACKRF_SUCCESS; @@ -944,6 +966,7 @@ int ADDCALL hackrf_cpld_write(hackrf_device* device, ); if (result != LIBUSB_SUCCESS) { + last_libusb_error = result; return HACKRF_ERROR_LIBUSB; } } @@ -967,6 +990,7 @@ int ADDCALL hackrf_board_id_read(hackrf_device* device, uint8_t* value) if (result < 1) { + last_libusb_error = result; return HACKRF_ERROR_LIBUSB; } else { return HACKRF_SUCCESS; @@ -990,6 +1014,7 @@ int ADDCALL hackrf_version_string_read(hackrf_device* device, char* version, if (result < 0) { + last_libusb_error = result; return HACKRF_ERROR_LIBUSB; } else { version[result] = '\0'; @@ -1005,8 +1030,10 @@ extern ADDAPI int ADDCALL hackrf_usb_api_version_read(hackrf_device* device, struct libusb_device_descriptor desc; dev = libusb_get_device(device->usb_device); result = libusb_get_device_descriptor(dev, &desc); - if (result < 0) + if (result < 0) { + last_libusb_error = result; return HACKRF_ERROR_LIBUSB; + } *version = desc.bcdDevice; return HACKRF_SUCCESS; @@ -1053,6 +1080,7 @@ int ADDCALL hackrf_set_freq(hackrf_device* device, const uint64_t freq_hz) if (result < length) { + last_libusb_error = result; return HACKRF_ERROR_LIBUSB; } else { return HACKRF_SUCCESS; @@ -1104,6 +1132,7 @@ int ADDCALL hackrf_set_freq_explicit(hackrf_device* device, if (result < length) { + last_libusb_error = result; return HACKRF_ERROR_LIBUSB; } else { return HACKRF_SUCCESS; @@ -1145,6 +1174,7 @@ int ADDCALL hackrf_set_sample_rate_manual(hackrf_device* device, if (result < length) { + last_libusb_error = result; return HACKRF_ERROR_LIBUSB; } else { return hackrf_set_baseband_filter_bandwidth(device, @@ -1214,6 +1244,7 @@ int ADDCALL hackrf_set_amp_enable(hackrf_device* device, const uint8_t value) if (result != 0) { + last_libusb_error = result; return HACKRF_ERROR_LIBUSB; } else { return HACKRF_SUCCESS; @@ -1239,6 +1270,7 @@ int ADDCALL hackrf_board_partid_serialno_read(hackrf_device* device, read_partid if (result < length) { + last_libusb_error = result; return HACKRF_ERROR_LIBUSB; } else { @@ -1358,6 +1390,7 @@ int ADDCALL hackrf_set_antenna_enable(hackrf_device* device, const uint8_t value if (result != 0) { + last_libusb_error = result; return HACKRF_ERROR_LIBUSB; } else { return HACKRF_SUCCESS; @@ -1606,6 +1639,10 @@ const char* ADDCALL hackrf_error_name(enum hackrf_error errcode) return "insufficient memory"; case HACKRF_ERROR_LIBUSB: +#if defined(LIBUSB_API_VERSION) && (LIBUSB_API_VERSION >= 0x01000103) + if(last_libusb_error != LIBUSB_SUCCESS) + return libusb_strerror(last_libusb_error); +#endif return "USB error"; case HACKRF_ERROR_THREAD: @@ -1750,6 +1787,7 @@ int ADDCALL hackrf_set_hw_sync_mode(hackrf_device* device, const uint8_t value) if( result != 0 ) { + last_libusb_error = result; return HACKRF_ERROR_LIBUSB; } else { return HACKRF_SUCCESS; @@ -1778,6 +1816,7 @@ int ADDCALL hackrf_init_sweep(hackrf_device* device, uint16_t* frequency_list, i ); if (result < size) { + last_libusb_error = result; return HACKRF_ERROR_LIBUSB; } else { return HACKRF_SUCCESS; @@ -1804,6 +1843,7 @@ int ADDCALL hackrf_get_operacake_boards(hackrf_device* device, uint8_t* boards) if (result < 8) { + last_libusb_error = result; return HACKRF_ERROR_LIBUSB; } else { return HACKRF_SUCCESS; @@ -1839,6 +1879,7 @@ int ADDCALL hackrf_set_operacake_ports(hackrf_device* device, ); if (result != 0) { + last_libusb_error = result; return HACKRF_ERROR_LIBUSB; } else { return HACKRF_SUCCESS; @@ -1859,6 +1900,7 @@ int ADDCALL hackrf_reset(hackrf_device* device) { ); if( result != 0 ) { + last_libusb_error = result; return HACKRF_ERROR_LIBUSB; } else { return HACKRF_SUCCESS; From b8aaee6e720c9267f8a9436f847f1df633b2e609 Mon Sep 17 00:00:00 2001 From: Dominic Spill Date: Fri, 3 Feb 2017 12:07:07 -0700 Subject: [PATCH 06/59] Correct usage for -d --- host/hackrf-tools/src/hackrf_operacake.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/host/hackrf-tools/src/hackrf_operacake.c b/host/hackrf-tools/src/hackrf_operacake.c index 649f9902..0b8405b6 100644 --- a/host/hackrf-tools/src/hackrf_operacake.c +++ b/host/hackrf-tools/src/hackrf_operacake.c @@ -34,7 +34,7 @@ typedef int bool; static void usage() { printf("\nUsage:\n"); printf("\t-h, --help: this help\n"); - printf("\t-d, --device : specify a particular device by number\n"); + printf("\t-d, --device : specify a particular device by serial 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"); From 8ee70526601fb58bfd80cb4994529037c8818b39 Mon Sep 17 00:00:00 2001 From: Michael Ossmann Date: Fri, 3 Feb 2017 16:38:06 -0700 Subject: [PATCH 07/59] Added csv text output to hackrf_sweep. Added -B option for binary output. Text output is now the default. Removed binary dump of raw samples between FFTs. --- host/hackrf-tools/src/hackrf_sweep.c | 53 ++++++++++++++++++---------- 1 file changed, 35 insertions(+), 18 deletions(-) diff --git a/host/hackrf-tools/src/hackrf_sweep.c b/host/hackrf-tools/src/hackrf_sweep.c index dca716cf..8d0727a1 100644 --- a/host/hackrf-tools/src/hackrf_sweep.c +++ b/host/hackrf-tools/src/hackrf_sweep.c @@ -36,6 +36,10 @@ #include #define _FILE_OFFSET_BITS 64 +#define BLOCKS_PER_TRANSFER 16 +#define SAMPLES_PER_BLOCK 16384 +#define STEP_SIZE_IN_HZ 312500 +#define FFT_SIZE 64 #ifndef bool typedef int bool; @@ -169,12 +173,17 @@ uint32_t antenna_enable; uint32_t freq_min; uint32_t freq_max; +bool binary_output = false; + int fftSize; fftwf_complex *fftwIn = NULL; fftwf_complex *fftwOut = NULL; fftwf_plan fftwPlan = NULL; float* pwr; float* window; +time_t time_now; +struct tm *fft_time; +char time_str[50]; float logPower(fftwf_complex in, float scale) { @@ -190,22 +199,19 @@ int rx_callback(hackrf_transfer* transfer) { * Throw away unused bins * write output to pipe */ - ssize_t bytes_to_write; - ssize_t bytes_written; int8_t* buf; float frequency; int i, j; if( fd != NULL ) { byte_count += transfer->valid_length; - bytes_to_write = transfer->valid_length; buf = (int8_t*) transfer->buffer; - for(j=0; j<16; j++) { + for(j=0; j> 1); pwr[i] = logPower(fftwOut[k], 1.0f / fftSize); } - fwrite(&frequency, sizeof(float), 1, stdout); - fwrite(pwr, sizeof(float), fftSize, stdout); - } - - bytes_written = fwrite(transfer->buffer, 1, bytes_to_write, fd); - if (bytes_written != bytes_to_write) { - return -1; - } else { - return 0; + if(binary_output) { + fwrite(&frequency, sizeof(float), 1, stdout); + fwrite(pwr, sizeof(float), fftSize, stdout); + } else { + time_now = time(NULL); + fft_time = localtime(&time_now); + strftime(time_str, 50, "%Y-%m-%d, %H:%M:%S", fft_time); + printf("%s, hz_low, hz_high, hz_step, num_samples, ", time_str); + for(i=0; i < (fftSize - 1); i++) { + printf("%.2f, ", pwr[i]); + } + printf("%.2f\n", pwr[fftSize - 1]); + } } + return 0; } else { return -1; } @@ -243,6 +255,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[-n num_samples] # Number of samples per frequency, 16384-4294967296\n"); + fprintf(stderr, "\t[-B] # binary output\n"); } static hackrf_device* device = NULL; @@ -276,7 +289,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:d:n:h?")) != EOF ) { + while( (opt = getopt(argc, argv, "a:f:p:l:g:d:n:Bh?")) != EOF ) { result = HACKRF_SUCCESS; switch( opt ) { @@ -321,6 +334,10 @@ int main(int argc, char** argv) { result = parse_u32(optarg, &num_samples); break; + case 'B': + binary_output = true; + break; + case 'h': case '?': usage(); @@ -345,12 +362,12 @@ int main(int argc, char** argv) { if (vga_gain % 2) fprintf(stderr, "warning: vga_gain (-g) must be a multiple of 2\n"); - if (num_samples % 0x4000) { + if (num_samples % SAMPLES_PER_BLOCK) { fprintf(stderr, "warning: num_samples (-n) must be a multiple of 16384\n"); return EXIT_FAILURE; } - if (num_samples < 0x4000) { + if (num_samples < SAMPLES_PER_BLOCK) { fprintf(stderr, "warning: num_samples (-n) must be at least 16384\n"); return EXIT_FAILURE; } @@ -377,7 +394,7 @@ int main(int argc, char** argv) { return EXIT_FAILURE; } - fftSize = 64; + fftSize = FFT_SIZE; fftwIn = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex) * fftSize); fftwOut = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex) * fftSize); fftwPlan = fftwf_plan_dft_1d(fftSize, fftwIn, fftwOut, FFTW_FORWARD, FFTW_MEASURE); From a51f06350eaf45cf19805059d38e37e321638085 Mon Sep 17 00:00:00 2001 From: Michael Ossmann Date: Fri, 3 Feb 2017 17:08:11 -0700 Subject: [PATCH 08/59] print actual values for all fields in hackrf_sweep csv output --- host/hackrf-tools/src/hackrf_sweep.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/host/hackrf-tools/src/hackrf_sweep.c b/host/hackrf-tools/src/hackrf_sweep.c index 8d0727a1..03ae392c 100644 --- a/host/hackrf-tools/src/hackrf_sweep.c +++ b/host/hackrf-tools/src/hackrf_sweep.c @@ -34,6 +34,7 @@ #include #include #include +#include #define _FILE_OFFSET_BITS 64 #define BLOCKS_PER_TRANSFER 16 @@ -232,7 +233,12 @@ int rx_callback(hackrf_transfer* transfer) { time_now = time(NULL); fft_time = localtime(&time_now); strftime(time_str, 50, "%Y-%m-%d, %H:%M:%S", fft_time); - printf("%s, hz_low, hz_high, hz_step, num_samples, ", time_str); + printf("%s, %" PRIu64 ", %" PRIu64 ", %f, %d, ", + time_str, + (uint64_t)((FREQ_ONE_MHZ*frequency)-STEP_SIZE_IN_HZ*(FFT_SIZE/2)), + (uint64_t)((FREQ_ONE_MHZ*frequency)+STEP_SIZE_IN_HZ*(FFT_SIZE/2)), + (float)STEP_SIZE_IN_HZ, + FFT_SIZE); for(i=0; i < (fftSize - 1); i++) { printf("%.2f, ", pwr[i]); } From bb350dccc0e7d6bd404f8448cdcd380a984fc62c Mon Sep 17 00:00:00 2001 From: Michael Ossmann Date: Fri, 3 Feb 2017 17:44:10 -0700 Subject: [PATCH 09/59] fixed off-by-one error in hackrf_sweep --- host/hackrf-tools/src/hackrf_sweep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/host/hackrf-tools/src/hackrf_sweep.c b/host/hackrf-tools/src/hackrf_sweep.c index 03ae392c..d50122eb 100644 --- a/host/hackrf-tools/src/hackrf_sweep.c +++ b/host/hackrf-tools/src/hackrf_sweep.c @@ -235,7 +235,7 @@ int rx_callback(hackrf_transfer* transfer) { strftime(time_str, 50, "%Y-%m-%d, %H:%M:%S", fft_time); printf("%s, %" PRIu64 ", %" PRIu64 ", %f, %d, ", time_str, - (uint64_t)((FREQ_ONE_MHZ*frequency)-STEP_SIZE_IN_HZ*(FFT_SIZE/2)), + (uint64_t)((FREQ_ONE_MHZ*frequency)+1-STEP_SIZE_IN_HZ*(FFT_SIZE/2)), (uint64_t)((FREQ_ONE_MHZ*frequency)+STEP_SIZE_IN_HZ*(FFT_SIZE/2)), (float)STEP_SIZE_IN_HZ, FFT_SIZE); From 586082e3e5067fce0fb937f03cc9970eebcd874e Mon Sep 17 00:00:00 2001 From: Michael Ossmann Date: Fri, 3 Feb 2017 17:48:16 -0700 Subject: [PATCH 10/59] fixed off-by-one error in hackrf_sweep again --- host/hackrf-tools/src/hackrf_sweep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/host/hackrf-tools/src/hackrf_sweep.c b/host/hackrf-tools/src/hackrf_sweep.c index d50122eb..cc71059c 100644 --- a/host/hackrf-tools/src/hackrf_sweep.c +++ b/host/hackrf-tools/src/hackrf_sweep.c @@ -235,7 +235,7 @@ int rx_callback(hackrf_transfer* transfer) { strftime(time_str, 50, "%Y-%m-%d, %H:%M:%S", fft_time); printf("%s, %" PRIu64 ", %" PRIu64 ", %f, %d, ", time_str, - (uint64_t)((FREQ_ONE_MHZ*frequency)+1-STEP_SIZE_IN_HZ*(FFT_SIZE/2)), + (uint64_t)((FREQ_ONE_MHZ*frequency)-STEP_SIZE_IN_HZ*((FFT_SIZE/2)-1)), (uint64_t)((FREQ_ONE_MHZ*frequency)+STEP_SIZE_IN_HZ*(FFT_SIZE/2)), (float)STEP_SIZE_IN_HZ, FFT_SIZE); From c07fb8579c580bb86b93709c0695e15a054ccd15 Mon Sep 17 00:00:00 2001 From: Dominic Spill Date: Sat, 4 Feb 2017 00:03:46 -0700 Subject: [PATCH 11/59] hackrf_transfer initialisation was using unusual syntax --- host/libhackrf/src/hackrf.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/host/libhackrf/src/hackrf.c b/host/libhackrf/src/hackrf.c index c858f66d..26cbcd46 100644 --- a/host/libhackrf/src/hackrf.c +++ b/host/libhackrf/src/hackrf.c @@ -1422,12 +1422,12 @@ static void hackrf_libusb_transfer_callback(struct libusb_transfer* usb_transfer if(usb_transfer->status == LIBUSB_TRANSFER_COMPLETED) { hackrf_transfer transfer = { - transfer.device = device, - transfer.buffer = usb_transfer->buffer, - transfer.buffer_length = usb_transfer->length, - transfer.valid_length = usb_transfer->actual_length, - transfer.rx_ctx = device->rx_ctx, - transfer.tx_ctx = device->tx_ctx + .device = device, + .buffer = usb_transfer->buffer, + .buffer_length = usb_transfer->length, + .valid_length = usb_transfer->actual_length, + .rx_ctx = device->rx_ctx, + .tx_ctx = device->tx_ctx }; if( device->callback(&transfer) == 0 ) From 35df00bd84b9683524c941251846876530ab32f0 Mon Sep 17 00:00:00 2001 From: Dominic Spill Date: Sat, 4 Feb 2017 00:06:23 -0700 Subject: [PATCH 12/59] Remove repeated check for fd==NULL --- host/hackrf-tools/src/hackrf_spiflash.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/host/hackrf-tools/src/hackrf_spiflash.c b/host/hackrf-tools/src/hackrf_spiflash.c index fabdb382..aa30dfcd 100644 --- a/host/hackrf-tools/src/hackrf_spiflash.c +++ b/host/hackrf-tools/src/hackrf_spiflash.c @@ -226,11 +226,6 @@ int main(int argc, char** argv) } } - if((read || write) && (fd == NULL)) { - fprintf(stderr, "Failed to open file: %s\n", path); - return EXIT_FAILURE; - } - result = hackrf_init(); if (result != HACKRF_SUCCESS) { fprintf(stderr, "hackrf_init() failed: %s (%d)\n", From bcbb7cc2e30118932d77a8d19d67fae0a1333e8a Mon Sep 17 00:00:00 2001 From: Dominic Spill Date: Sat, 4 Feb 2017 00:07:30 -0700 Subject: [PATCH 13/59] Remove unused test for result in opt parsing --- host/hackrf-tools/src/hackrf_operacake.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/host/hackrf-tools/src/hackrf_operacake.c b/host/hackrf-tools/src/hackrf_operacake.c index 0b8405b6..3a77c8ab 100644 --- a/host/hackrf-tools/src/hackrf_operacake.c +++ b/host/hackrf-tools/src/hackrf_operacake.c @@ -112,11 +112,6 @@ int main(int argc, char** argv) { usage(); return EXIT_FAILURE; } - - if( result != HACKRF_SUCCESS ) { - printf("argument error: %s (%d)\n", hackrf_error_name(result), result); - break; - } } if(!(list || set_ports)) { From 8902a502452dfd0def7521be72bbd7f71a290a96 Mon Sep 17 00:00:00 2001 From: Dominic Spill Date: Sat, 4 Feb 2017 00:08:48 -0700 Subject: [PATCH 14/59] Remove unused error checking code --- host/hackrf-tools/src/hackrf_cpldjtag.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/host/hackrf-tools/src/hackrf_cpldjtag.c b/host/hackrf-tools/src/hackrf_cpldjtag.c index fc82deb4..bdd7c051 100644 --- a/host/hackrf-tools/src/hackrf_cpldjtag.c +++ b/host/hackrf-tools/src/hackrf_cpldjtag.c @@ -120,13 +120,6 @@ int main(int argc, char** argv) usage(); return EXIT_FAILURE; } - - if (result != HACKRF_SUCCESS) { - fprintf(stderr, "argument error: %s (%d)\n", - hackrf_error_name(result), result); - usage(); - return EXIT_FAILURE; - } } if (path == NULL) { From 74aea3266ee7c0a7a27a55ad2392e6979ed03f46 Mon Sep 17 00:00:00 2001 From: Michael Ossmann Date: Sat, 4 Feb 2017 09:58:04 -0700 Subject: [PATCH 15/59] Made hackrf_sweep output more like rtl_power's. --- host/hackrf-tools/src/hackrf_sweep.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/host/hackrf-tools/src/hackrf_sweep.c b/host/hackrf-tools/src/hackrf_sweep.c index cc71059c..399799b9 100644 --- a/host/hackrf-tools/src/hackrf_sweep.c +++ b/host/hackrf-tools/src/hackrf_sweep.c @@ -201,7 +201,8 @@ int rx_callback(hackrf_transfer* transfer) { * write output to pipe */ int8_t* buf; - float frequency; + uint16_t frequency; + float float_freq; int i, j; if( fd != NULL ) { @@ -210,6 +211,13 @@ int rx_callback(hackrf_transfer* transfer) { for(j=0; j Date: Sat, 4 Feb 2017 10:07:17 -0700 Subject: [PATCH 16/59] consolidated a little code in hackrf_sweep --- host/hackrf-tools/src/hackrf_sweep.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/host/hackrf-tools/src/hackrf_sweep.c b/host/hackrf-tools/src/hackrf_sweep.c index 399799b9..5a93daea 100644 --- a/host/hackrf-tools/src/hackrf_sweep.c +++ b/host/hackrf-tools/src/hackrf_sweep.c @@ -242,16 +242,16 @@ int rx_callback(hackrf_transfer* transfer) { time_now = time(NULL); fft_time = localtime(&time_now); strftime(time_str, 50, "%Y-%m-%d, %H:%M:%S", fft_time); - printf("%s, %" PRIu64 ", %" PRIu64 ", %.2f, %d, ", + printf("%s, %" PRIu64 ", %" PRIu64 ", %.2f, %d", time_str, (uint64_t)((FREQ_ONE_MHZ*frequency)-(DEFAULT_SAMPLE_RATE_HZ/2)), (uint64_t)((FREQ_ONE_MHZ*frequency)+(DEFAULT_SAMPLE_RATE_HZ/2)), (float)STEP_SIZE_IN_HZ, FFT_SIZE); - for(i=0; i < (fftSize - 1); i++) { - printf("%.2f, ", pwr[i]); + for(i=0; i < fftSize; i++) { + printf(", %.2f", pwr[i]); } - printf("%.2f\n", pwr[fftSize - 1]); + printf("\n"); } } return 0; From 8ec1fb32741a89b3bf35d487958155eb2844a811 Mon Sep 17 00:00:00 2001 From: Michael Ossmann Date: Sat, 4 Feb 2017 10:09:26 -0700 Subject: [PATCH 17/59] too many Hz --- host/hackrf-tools/src/hackrf_sweep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/host/hackrf-tools/src/hackrf_sweep.c b/host/hackrf-tools/src/hackrf_sweep.c index 5a93daea..f0ae1389 100644 --- a/host/hackrf-tools/src/hackrf_sweep.c +++ b/host/hackrf-tools/src/hackrf_sweep.c @@ -215,7 +215,7 @@ int rx_callback(hackrf_transfer* transfer) { buf += SAMPLES_PER_BLOCK; break; } - if((FREQ_MAX_HZ*FREQ_ONE_MHZ < frequency)) { + if((FREQ_MAX_HZ < frequency)) { buf += SAMPLES_PER_BLOCK; break; } From 93201702d66ab1e3c3a9a4a23a3c7ece8d52c796 Mon Sep 17 00:00:00 2001 From: Michael Ossmann Date: Sat, 4 Feb 2017 10:30:33 -0700 Subject: [PATCH 18/59] too few Hz --- host/hackrf-tools/src/hackrf_sweep.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/host/hackrf-tools/src/hackrf_sweep.c b/host/hackrf-tools/src/hackrf_sweep.c index f0ae1389..06e4441b 100644 --- a/host/hackrf-tools/src/hackrf_sweep.c +++ b/host/hackrf-tools/src/hackrf_sweep.c @@ -201,7 +201,7 @@ int rx_callback(hackrf_transfer* transfer) { * write output to pipe */ int8_t* buf; - uint16_t frequency; + uint16_t frequency; /* in MHz */ float float_freq; int i, j; @@ -215,7 +215,7 @@ int rx_callback(hackrf_transfer* transfer) { buf += SAMPLES_PER_BLOCK; break; } - if((FREQ_MAX_HZ < frequency)) { + if(FREQ_MAX_HZ < (FREQ_ONE_MHZ*frequency)) { buf += SAMPLES_PER_BLOCK; break; } From 3ad5113201df7624ae25da5c67b3de62aca8760d Mon Sep 17 00:00:00 2001 From: Michael Ossmann Date: Sat, 4 Feb 2017 10:43:33 -0700 Subject: [PATCH 19/59] Select only the best sections of the FFT output. Skip the lowest 1/8 of the band, the middle 1/4 of the band, and the highest 1/8 of the band. This provides full coverage of the selected frequency range because the hopping pattern was designed with this in mind. --- host/hackrf-tools/src/hackrf_sweep.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/host/hackrf-tools/src/hackrf_sweep.c b/host/hackrf-tools/src/hackrf_sweep.c index 06e4441b..910d6b84 100644 --- a/host/hackrf-tools/src/hackrf_sweep.c +++ b/host/hackrf-tools/src/hackrf_sweep.c @@ -244,11 +244,21 @@ int rx_callback(hackrf_transfer* transfer) { strftime(time_str, 50, "%Y-%m-%d, %H:%M:%S", fft_time); printf("%s, %" PRIu64 ", %" PRIu64 ", %.2f, %d", time_str, - (uint64_t)((FREQ_ONE_MHZ*frequency)-(DEFAULT_SAMPLE_RATE_HZ/2)), - (uint64_t)((FREQ_ONE_MHZ*frequency)+(DEFAULT_SAMPLE_RATE_HZ/2)), + (uint64_t)((FREQ_ONE_MHZ*frequency)-((DEFAULT_SAMPLE_RATE_HZ*3)/8)), + (uint64_t)((FREQ_ONE_MHZ*frequency)-(DEFAULT_SAMPLE_RATE_HZ/8)), (float)STEP_SIZE_IN_HZ, FFT_SIZE); - for(i=0; i < fftSize; i++) { + for(i=fftSize/8; (fftSize*3)/8 > i; i++) { + printf(", %.2f", pwr[i]); + } + printf("\n"); + printf("%s, %" PRIu64 ", %" PRIu64 ", %.2f, %d", + time_str, + (uint64_t)((FREQ_ONE_MHZ*frequency)+(DEFAULT_SAMPLE_RATE_HZ/8)), + (uint64_t)((FREQ_ONE_MHZ*frequency)+((DEFAULT_SAMPLE_RATE_HZ*3)/8)), + (float)STEP_SIZE_IN_HZ, + FFT_SIZE); + for(i=(fftSize*5)/8; (fftSize*7)/8 > i; i++) { printf(", %.2f", pwr[i]); } printf("\n"); From 38c67f7e8992f4859eaa6297ff700e511c03b856 Mon Sep 17 00:00:00 2001 From: Dominic Spill Date: Sun, 5 Feb 2017 21:40:57 -0700 Subject: [PATCH 20/59] Add printable libhackrf and hackrf tools version strings --- host/CMakeLists.txt | 18 ++++++++++++++++++ host/hackrf-tools/CMakeLists.txt | 5 +---- host/hackrf-tools/src/hackrf_info.c | 4 ++++ host/libhackrf/CMakeLists.txt | 4 +++- host/libhackrf/src/hackrf.c | 16 ++++++++++++++++ host/libhackrf/src/hackrf.h | 3 +++ 6 files changed, 45 insertions(+), 5 deletions(-) diff --git a/host/CMakeLists.txt b/host/CMakeLists.txt index 874163f8..96965b7a 100644 --- a/host/CMakeLists.txt +++ b/host/CMakeLists.txt @@ -3,6 +3,24 @@ cmake_minimum_required(VERSION 2.8) project (hackrf_all) +#set(RELEASE "") + +if(NOT DEFINED RELEASE) + execute_process( + COMMAND git log -n 1 --format=%h + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + RESULT_VARIABLE GIT_VERSION_FOUND + ERROR_QUIET + OUTPUT_VARIABLE GIT_VERSION + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + if (GIT_VERSION_FOUND) + set(RELEASE "unknown") + else (GIT_VERSION_FOUND) + set(RELEASE "git-${GIT_VERSION}") + endif (GIT_VERSION_FOUND) +endif() + add_subdirectory(libhackrf) add_subdirectory(hackrf-tools) diff --git a/host/hackrf-tools/CMakeLists.txt b/host/hackrf-tools/CMakeLists.txt index 82ea47d8..18dbf007 100644 --- a/host/hackrf-tools/CMakeLists.txt +++ b/host/hackrf-tools/CMakeLists.txt @@ -23,11 +23,8 @@ cmake_minimum_required(VERSION 2.8) project(hackrf-tools C) -set(MAJOR_VERSION 0) -set(MINOR_VERSION 5) set(PACKAGE hackrf-tools) -set(VERSION_STRING ${MAJOR_VERSION}.${MINOR_VERSION}) -set(VERSION ${VERSION_STRING}) +add_definitions(-DTOOL_RELEASE="${RELEASE}") set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/../cmake/modules) if(MSVC) diff --git a/host/hackrf-tools/src/hackrf_info.c b/host/hackrf-tools/src/hackrf_info.c index 0049a3e7..abb72887 100644 --- a/host/hackrf-tools/src/hackrf_info.c +++ b/host/hackrf-tools/src/hackrf_info.c @@ -44,6 +44,10 @@ int main(void) hackrf_error_name(result), result); return EXIT_FAILURE; } + + printf("hackrf_info version: %s\n", TOOL_RELEASE); + printf("libhackrf version: %s (%s)\n", hackrf_library_release(), + hackrf_library_version()); list = hackrf_device_list(); diff --git a/host/libhackrf/CMakeLists.txt b/host/libhackrf/CMakeLists.txt index c898d233..c3cd4946 100644 --- a/host/libhackrf/CMakeLists.txt +++ b/host/libhackrf/CMakeLists.txt @@ -24,10 +24,12 @@ cmake_minimum_required(VERSION 2.8) project(libhackrf C) set(MAJOR_VERSION 0) -set(MINOR_VERSION 4) +set(MINOR_VERSION 5) set(PACKAGE libhackrf) set(VERSION_STRING ${MAJOR_VERSION}.${MINOR_VERSION}) set(VERSION ${VERSION_STRING}) +add_definitions(-DLIBRARY_VERSION="${VERSION_STRING}") +add_definitions(-DLIBRARY_RELEASE="${RELEASE}") set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/../cmake/modules) if(MSVC) diff --git a/host/libhackrf/src/hackrf.c b/host/libhackrf/src/hackrf.c index c858f66d..a6925611 100644 --- a/host/libhackrf/src/hackrf.c +++ b/host/libhackrf/src/hackrf.c @@ -365,6 +365,22 @@ int ADDCALL hackrf_exit(void) return HACKRF_SUCCESS; } +#ifndef LIBRARY_VERSION +#define LIBRARY_VERSION "unknown" +#endif +const char* ADDCALL hackrf_library_version() +{ + return LIBRARY_VERSION; +} + +#ifndef LIBRARY_RELEASE +#define LIBRARY_RELEASE "unknown" +#endif +const char* ADDCALL hackrf_library_release() +{ + return LIBRARY_RELEASE; +} + hackrf_device_list_t* ADDCALL hackrf_device_list() { ssize_t i; diff --git a/host/libhackrf/src/hackrf.h b/host/libhackrf/src/hackrf.h index d1a57c4d..904207e0 100644 --- a/host/libhackrf/src/hackrf.h +++ b/host/libhackrf/src/hackrf.h @@ -133,6 +133,9 @@ extern "C" extern ADDAPI int ADDCALL hackrf_init(); extern ADDAPI int ADDCALL hackrf_exit(); +extern ADDAPI const char* ADDCALL hackrf_library_version(); +extern ADDAPI const char* ADDCALL hackrf_library_release(); + extern ADDAPI hackrf_device_list_t* ADDCALL hackrf_device_list(); extern ADDAPI int ADDCALL hackrf_device_list_open(hackrf_device_list_t *list, int idx, hackrf_device** device); extern ADDAPI void ADDCALL hackrf_device_list_free(hackrf_device_list_t *list); From e66c8eec0130e1e11a5019a3343cf6a983547d9d Mon Sep 17 00:00:00 2001 From: Dominic Spill Date: Sun, 5 Feb 2017 22:35:51 -0700 Subject: [PATCH 21/59] Check function return values when reading registers --- host/hackrf-tools/src/hackrf_max2837.c | 21 ++++++++++++++++++--- host/hackrf-tools/src/hackrf_rffc5071.c | 15 +++++++++++++++ host/hackrf-tools/src/hackrf_si5351c.c | 17 +++++++++++++++-- 3 files changed, 48 insertions(+), 5 deletions(-) diff --git a/host/hackrf-tools/src/hackrf_max2837.c b/host/hackrf-tools/src/hackrf_max2837.c index f52ca9e1..f64761b3 100644 --- a/host/hackrf-tools/src/hackrf_max2837.c +++ b/host/hackrf-tools/src/hackrf_max2837.c @@ -199,13 +199,28 @@ int main(int argc, char** argv) { if(write) { result = write_register(device, register_number, register_value); - } + if(result) { + printf("dump_registers() failed: %s (%d)\n", + hackrf_error_name(result), result); + return EXIT_FAILURE; + } + } if(read) { if(register_number == REGISTER_INVALID) { result = dump_registers(device); - } else { - result = dump_register(device, register_number); + if(result) { + printf("dump_registers() failed: %s (%d)\n", + hackrf_error_name(result), result); + return EXIT_FAILURE; + } + } + } else { + result = dump_register(device, register_number); + if(result) { + printf("dump_registers() failed: %s (%d)\n", + hackrf_error_name(result), result); + return EXIT_FAILURE; } } diff --git a/host/hackrf-tools/src/hackrf_rffc5071.c b/host/hackrf-tools/src/hackrf_rffc5071.c index 867bc379..f9d478e3 100644 --- a/host/hackrf-tools/src/hackrf_rffc5071.c +++ b/host/hackrf-tools/src/hackrf_rffc5071.c @@ -196,13 +196,28 @@ int main(int argc, char** argv) { if(write) { result = write_register(device, register_number, register_value); + if(result) { + printf("dump_registers() failed: %s (%d)\n", + hackrf_error_name(result), result); + return EXIT_FAILURE; + } } if(read) { if(register_number == REGISTER_INVALID) { result = dump_registers(device); + if(result) { + printf("dump_registers() failed: %s (%d)\n", + hackrf_error_name(result), result); + return EXIT_FAILURE; + } } else { result = dump_register(device, register_number); + if(result) { + printf("dump_registers() failed: %s (%d)\n", + hackrf_error_name(result), result); + return EXIT_FAILURE; + } } } diff --git a/host/hackrf-tools/src/hackrf_si5351c.c b/host/hackrf-tools/src/hackrf_si5351c.c index 7c8712c4..7b01f947 100644 --- a/host/hackrf-tools/src/hackrf_si5351c.c +++ b/host/hackrf-tools/src/hackrf_si5351c.c @@ -292,16 +292,29 @@ int main(int argc, char** argv) { } if(write) { - if( result == HACKRF_SUCCESS ) { - result = write_register(device, register_number, register_value); + result = write_register(device, register_number, register_value); + if(result) { + printf("dump_registers() failed: %s (%d)\n", + hackrf_error_name(result), result); + return EXIT_FAILURE; } } if(read) { if( register_number == REGISTER_INVALID ) { result = dump_registers(device); + if(result) { + printf("dump_registers() failed: %s (%d)\n", + hackrf_error_name(result), result); + return EXIT_FAILURE; + } } else { result = dump_register(device, register_number); + if(result) { + printf("dump_registers() failed: %s (%d)\n", + hackrf_error_name(result), result); + return EXIT_FAILURE; + } } } From a44875a7a0f25a25b42f75168e20342212f5a1e2 Mon Sep 17 00:00:00 2001 From: Dominic Spill Date: Mon, 6 Feb 2017 10:57:09 -0700 Subject: [PATCH 22/59] Add dirty flag to host versions --- host/CMakeLists.txt | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/host/CMakeLists.txt b/host/CMakeLists.txt index 96965b7a..69b0ef31 100644 --- a/host/CMakeLists.txt +++ b/host/CMakeLists.txt @@ -9,16 +9,25 @@ if(NOT DEFINED RELEASE) execute_process( COMMAND git log -n 1 --format=%h WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - RESULT_VARIABLE GIT_VERSION_FOUND + RESULT_VARIABLE GIT_EXIT_VALUE ERROR_QUIET OUTPUT_VARIABLE GIT_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE ) - if (GIT_VERSION_FOUND) + if (GIT_EXIT_VALUE) set(RELEASE "unknown") - else (GIT_VERSION_FOUND) - set(RELEASE "git-${GIT_VERSION}") - endif (GIT_VERSION_FOUND) + else (GIT_EXIT_VALUE) + execute_process( + COMMAND git status -s --untracked-files=no + OUTPUT_VARIABLE DIRTY + ) + if ( NOT "${DIRTY}" STREQUAL "" ) + set(DIRTY_FLAG "*") + else() + set(DIRTY_FLAG "") + endif() + set(RELEASE "git-${GIT_VERSION}${DIRTY_FLAG}") + endif (GIT_EXIT_VALUE) endif() add_subdirectory(libhackrf) From d3b30eca594c647488d43dccce1b97d5a8105517 Mon Sep 17 00:00:00 2001 From: Michael Ossmann Date: Mon, 6 Feb 2017 20:39:14 -0700 Subject: [PATCH 23/59] default frequency range and error checking of frequency range in hackrf_sweep --- host/hackrf-tools/src/hackrf_sweep.c | 59 +++++++++++++++++----------- 1 file changed, 36 insertions(+), 23 deletions(-) diff --git a/host/hackrf-tools/src/hackrf_sweep.c b/host/hackrf-tools/src/hackrf_sweep.c index 910d6b84..719a44a2 100644 --- a/host/hackrf-tools/src/hackrf_sweep.c +++ b/host/hackrf-tools/src/hackrf_sweep.c @@ -92,13 +92,13 @@ int gettimeofday(struct timeval *tv, void* ignored) { #define FREQ_ONE_MHZ (1000000ull) -#define FREQ_MIN_HZ (0ull) /* 0 Hz */ -#define FREQ_MAX_HZ (7250000000ull) /* 7250MHz */ +#define FREQ_MIN_MHZ (0) /* 0 MHz */ +#define FREQ_MAX_MHZ (7250) /* 7250 MHz */ #define DEFAULT_SAMPLE_RATE_HZ (20000000) /* 20MHz default sample rate */ #define DEFAULT_BASEBAND_FILTER_BANDWIDTH (15000000) /* 5MHz default */ -#define FREQ_STEP (DEFAULT_SAMPLE_RATE_HZ / FREQ_ONE_MHZ) +#define TUNE_STEP (DEFAULT_SAMPLE_RATE_HZ / FREQ_ONE_MHZ) #define MAX_FREQ_COUNT 1000 #define DEFAULT_SAMPLE_COUNT 0x4000 @@ -171,8 +171,8 @@ uint32_t amp_enable; bool antenna = false; uint32_t antenna_enable; -uint32_t freq_min; -uint32_t freq_max; +uint32_t freq_min = 10; +uint32_t freq_max = 6000; bool binary_output = false; @@ -215,7 +215,7 @@ int rx_callback(hackrf_transfer* transfer) { buf += SAMPLES_PER_BLOCK; break; } - if(FREQ_MAX_HZ < (FREQ_ONE_MHZ*frequency)) { + if(FREQ_MAX_MHZ < frequency) { buf += SAMPLES_PER_BLOCK; break; } @@ -242,7 +242,7 @@ int rx_callback(hackrf_transfer* transfer) { time_now = time(NULL); fft_time = localtime(&time_now); strftime(time_str, 50, "%Y-%m-%d, %H:%M:%S", fft_time); - printf("%s, %" PRIu64 ", %" PRIu64 ", %.2f, %d", + printf("%s, %" PRIu64 ", %" PRIu64 ", %.2f, %u", time_str, (uint64_t)((FREQ_ONE_MHZ*frequency)-((DEFAULT_SAMPLE_RATE_HZ*3)/8)), (uint64_t)((FREQ_ONE_MHZ*frequency)-(DEFAULT_SAMPLE_RATE_HZ/8)), @@ -252,7 +252,7 @@ int rx_callback(hackrf_transfer* transfer) { printf(", %.2f", pwr[i]); } printf("\n"); - printf("%s, %" PRIu64 ", %" PRIu64 ", %.2f, %d", + printf("%s, %" PRIu64 ", %" PRIu64 ", %.2f, %u", time_str, (uint64_t)((FREQ_ONE_MHZ*frequency)+(DEFAULT_SAMPLE_RATE_HZ/8)), (uint64_t)((FREQ_ONE_MHZ*frequency)+((DEFAULT_SAMPLE_RATE_HZ*3)/8)), @@ -275,7 +275,7 @@ static void usage() { 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 RF amplifier 1=Enable, 0=Disable.\n"); - fprintf(stderr, "\t[-f freq_min:freq_max # Specify minimum & maximum sweep frequencies (MHz).\n"); + fprintf(stderr, "\t[-f freq_min:freq_max] # Specify minimum & maximum sweep frequencies (MHz).\n"); fprintf(stderr, "\t[-p antenna_enable] # Antenna port power, 1=Enable, 0=Disable.\n"); 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"); @@ -313,6 +313,7 @@ int main(int argc, char** argv) { unsigned int lna_gain=16, vga_gain=20; uint16_t frequencies[MAX_FREQ_COUNT]; uint32_t num_samples = DEFAULT_SAMPLE_COUNT; + int step_count; while( (opt = getopt(argc, argv, "a:f:p:l:g:d:n:Bh?")) != EOF ) { result = HACKRF_SUCCESS; @@ -329,17 +330,6 @@ int main(int argc, char** argv) { case 'f': result = parse_u32_range(optarg, &freq_min, &freq_max); - fprintf(stderr, "Scanning %uMHz to %uMHz\n", freq_min, freq_max); - frequencies[ifreq++] = freq_min; - odd = true; - while(frequencies[ifreq-1] <= freq_max) { - if (odd) - frequencies[ifreq] = frequencies[ifreq-1] + FREQ_STEP / 4; - else - frequencies[ifreq] = frequencies[ifreq-1] + 3*(FREQ_STEP/4); - ifreq++; - odd = !odd; - } break; case 'p': @@ -413,12 +403,35 @@ int main(int argc, char** argv) { } } - if (ifreq == 0) { - fprintf(stderr, "argument error: must specify sweep frequency range (-f).\n"); + if (freq_min >= freq_max) { + fprintf(stderr, "argument error: freq_max must be greater than freq_min.\n"); usage(); return EXIT_FAILURE; } - + + /* Plan a whole number of steps with bandwidth equal to the sample rate. */ + step_count = 1 + (freq_max - freq_min - 1) / TUNE_STEP; + freq_max = freq_min + step_count * TUNE_STEP; + + if (FREQ_MAX_MHZ Date: Tue, 7 Feb 2017 13:57:49 -0700 Subject: [PATCH 24/59] Moved sweep mode frequency computation into firmware. Changed from long list of tuning frequencies to short list of ranges. --- firmware/hackrf_usb/usb_api_sweep.c | 90 +++++++++++++++++++++------- firmware/hackrf_usb/usb_api_sweep.h | 9 ++- host/hackrf-tools/src/hackrf_sweep.c | 70 +++++++++++----------- host/libhackrf/src/hackrf.c | 65 +++++++++++++++++--- host/libhackrf/src/hackrf.h | 15 ++++- 5 files changed, 179 insertions(+), 70 deletions(-) diff --git a/firmware/hackrf_usb/usb_api_sweep.c b/firmware/hackrf_usb/usb_api_sweep.c index 503e7f6a..c1a5f2b4 100644 --- a/firmware/hackrf_usb/usb_api_sweep.c +++ b/firmware/hackrf_usb/usb_api_sweep.c @@ -31,31 +31,55 @@ #define MIN(x,y) ((x)<(y)?(x):(y)) #define MAX(x,y) ((x)>(y)?(x):(y)) #define FREQ_GRANULARITY 1000000 -#define MIN_FREQ 1 -#define MAX_FREQ 6000 -#define MAX_FREQ_COUNT 1000 +#define MAX_RANGES 10 #define THROWAWAY_BUFFERS 2 volatile bool start_sweep_mode = false; static uint64_t sweep_freq; -bool odd = true; -static uint16_t frequencies[MAX_FREQ_COUNT]; -static uint16_t frequency_count = 0; +static bool odd = true; +static uint16_t frequencies[MAX_RANGES * 2]; +static unsigned char data[9 + MAX_RANGES * 2 * sizeof(frequencies[0])]; +static uint16_t num_ranges = 0; static uint32_t dwell_blocks = 0; +static uint32_t step_width = 0; +static uint32_t offset = 0; +static enum sweep_style style = LINEAR; +static uint16_t range = 0; usb_request_status_t usb_vendor_request_init_sweep( usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) { - uint32_t dwell_time; + uint32_t num_samples; + int i; if (stage == USB_TRANSFER_STAGE_SETUP) { - dwell_time = (endpoint->setup.index << 16) | endpoint->setup.value; - dwell_blocks = dwell_time / 0x4000; - frequency_count = endpoint->setup.length / sizeof(uint16_t); - usb_transfer_schedule_block(endpoint->out, &frequencies, - endpoint->setup.length, NULL, NULL); + num_samples = (endpoint->setup.index << 16) | endpoint->setup.value; + dwell_blocks = num_samples / 0x4000; + if(1 > dwell_blocks) { + return USB_REQUEST_STATUS_STALL; + } + num_ranges = (endpoint->setup.length - 9) / (2 * sizeof(frequencies[0])); + if((1 > num_ranges) || (MAX_RANGES < num_ranges)) { + return USB_REQUEST_STATUS_STALL; + } + usb_transfer_schedule_block(endpoint->out, &data, + endpoint->setup.length, NULL, NULL); } else if (stage == USB_TRANSFER_STAGE_DATA) { - sweep_freq = frequencies[0]; - set_freq(sweep_freq*FREQ_GRANULARITY); + step_width = ((uint32_t)(data[3]) << 24) | ((uint32_t)(data[2]) << 16) + | ((uint32_t)(data[1]) << 8) | data[0]; + if(1 > step_width) { + return USB_REQUEST_STATUS_STALL; + } + offset = ((uint32_t)(data[7]) << 24) | ((uint32_t)(data[6]) << 16) + | ((uint32_t)(data[5]) << 8) | data[4]; + style = data[8]; + if(INTERLEAVED < style) { + return USB_REQUEST_STATUS_STALL; + } + for(i=0; i<(num_ranges*2); i++) { + frequencies[i] = ((uint16_t)(data[10+i*2]) << 8) + data[9+i*2]; + } + sweep_freq = frequencies[0] * FREQ_GRANULARITY; + set_freq(sweep_freq + offset); start_sweep_mode = true; usb_transfer_schedule_ack(endpoint->in); } @@ -65,7 +89,6 @@ usb_request_status_t usb_vendor_request_init_sweep( void sweep_mode(void) { unsigned int blocks_queued = 0; unsigned int phase = 0; - unsigned int ifreq = 0; uint8_t *buffer; bool transfer = false; @@ -88,8 +111,16 @@ void sweep_mode(void) { } if (transfer) { - *(uint16_t*)buffer = 0x7F7F; - *(uint16_t*)(buffer+2) = sweep_freq; + *buffer = 0x7f; + *(buffer+1) = 0x7f; + *(buffer+2) = sweep_freq & 0xff; + *(buffer+3) = (sweep_freq >> 8) & 0xff; + *(buffer+4) = (sweep_freq >> 16) & 0xff; + *(buffer+5) = (sweep_freq >> 24) & 0xff; + *(buffer+6) = (sweep_freq >> 32) & 0xff; + *(buffer+7) = (sweep_freq >> 40) & 0xff; + *(buffer+8) = (sweep_freq >> 48) & 0xff; + *(buffer+9) = (sweep_freq >> 56) & 0xff; if (blocks_queued > THROWAWAY_BUFFERS) { usb_transfer_schedule_block( &usb_endpoint_bulk_in, @@ -102,10 +133,27 @@ void sweep_mode(void) { } if ((dwell_blocks + THROWAWAY_BUFFERS) <= blocks_queued) { - if(++ifreq >= frequency_count) - ifreq = 0; - sweep_freq = frequencies[ifreq]; - set_freq(sweep_freq*FREQ_GRANULARITY); + if(INTERLEAVED == style) { + if(!odd && ((sweep_freq + step_width) >= ((uint64_t)frequencies[1+range*2] * FREQ_GRANULARITY))) { + range = (range + 1) % num_ranges; + sweep_freq = frequencies[range*2] * FREQ_GRANULARITY; + } else { + if(odd) { + sweep_freq += step_width/4; + } else { + sweep_freq += 3*step_width/4; + } + } + odd = !odd; + } else { + if((sweep_freq + step_width) >= ((uint64_t)frequencies[1+range*2] * FREQ_GRANULARITY)) { + range = (range + 1) % num_ranges; + sweep_freq = frequencies[range*2] * FREQ_GRANULARITY; + } else { + sweep_freq += step_width; + } + } + set_freq(sweep_freq + offset); blocks_queued = 0; } } diff --git a/firmware/hackrf_usb/usb_api_sweep.h b/firmware/hackrf_usb/usb_api_sweep.h index 828647cd..427c1cb2 100644 --- a/firmware/hackrf_usb/usb_api_sweep.h +++ b/firmware/hackrf_usb/usb_api_sweep.h @@ -19,8 +19,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef __USB_API_SCAN_H__ -#define __USB_API_SCAN_H__ +#ifndef __USB_API_SWEEP_H__ +#define __USB_API_SWEEP_H__ #include #include @@ -28,6 +28,11 @@ extern volatile bool start_sweep_mode; +enum sweep_style { + LINEAR = 0, + INTERLEAVED = 1, +}; + usb_request_status_t usb_vendor_request_init_sweep( usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); diff --git a/host/hackrf-tools/src/hackrf_sweep.c b/host/hackrf-tools/src/hackrf_sweep.c index 719a44a2..a5c0489c 100644 --- a/host/hackrf-tools/src/hackrf_sweep.c +++ b/host/hackrf-tools/src/hackrf_sweep.c @@ -37,10 +37,6 @@ #include #define _FILE_OFFSET_BITS 64 -#define BLOCKS_PER_TRANSFER 16 -#define SAMPLES_PER_BLOCK 16384 -#define STEP_SIZE_IN_HZ 312500 -#define FFT_SIZE 64 #ifndef bool typedef int bool; @@ -99,9 +95,12 @@ int gettimeofday(struct timeval *tv, void* ignored) { #define DEFAULT_BASEBAND_FILTER_BANDWIDTH (15000000) /* 5MHz default */ #define TUNE_STEP (DEFAULT_SAMPLE_RATE_HZ / FREQ_ONE_MHZ) -#define MAX_FREQ_COUNT 1000 +#define OFFSET 7500000 #define DEFAULT_SAMPLE_COUNT 0x4000 +#define BLOCKS_PER_TRANSFER 16 +#define FFT_BIN_WIDTH_HZ 312500 +#define FFT_SIZE 64 #if defined _WIN32 #define sleep(a) Sleep( (a*1000) ) @@ -201,7 +200,8 @@ int rx_callback(hackrf_transfer* transfer) { * write output to pipe */ int8_t* buf; - uint16_t frequency; /* in MHz */ + uint8_t* ubuf; + uint64_t frequency; /* in Hz */ float float_freq; int i, j; @@ -209,13 +209,16 @@ int rx_callback(hackrf_transfer* transfer) { byte_count += transfer->valid_length; buf = (int8_t*) transfer->buffer; for(j=0; j i; i++) { printf(", %.2f", pwr[i]); @@ -254,9 +258,9 @@ int rx_callback(hackrf_transfer* transfer) { printf("\n"); printf("%s, %" PRIu64 ", %" PRIu64 ", %.2f, %u", time_str, - (uint64_t)((FREQ_ONE_MHZ*frequency)+(DEFAULT_SAMPLE_RATE_HZ/8)), - (uint64_t)((FREQ_ONE_MHZ*frequency)+((DEFAULT_SAMPLE_RATE_HZ*3)/8)), - (float)STEP_SIZE_IN_HZ, + (uint64_t)(frequency+(DEFAULT_SAMPLE_RATE_HZ/2)), + (uint64_t)(frequency+((DEFAULT_SAMPLE_RATE_HZ*3)/4)), + (float)FFT_BIN_WIDTH_HZ, FFT_SIZE); for(i=(fftSize*5)/8; (fftSize*7)/8 > i; i++) { printf(", %.2f", pwr[i]); @@ -303,15 +307,14 @@ void sigint_callback_handler(int signum) { #endif int main(int argc, char** argv) { - int opt, i, result, ifreq = 0; - bool odd; + int opt, i, result = 0; const char* path = "/dev/null"; const char* serial_number = NULL; int exit_code = EXIT_SUCCESS; struct timeval t_end; float time_diff; unsigned int lna_gain=16, vga_gain=20; - uint16_t frequencies[MAX_FREQ_COUNT]; + uint16_t frequencies[MAX_SWEEP_RANGES*2]; uint32_t num_samples = DEFAULT_SAMPLE_COUNT; int step_count; @@ -409,10 +412,6 @@ int main(int argc, char** argv) { return EXIT_FAILURE; } - /* Plan a whole number of steps with bandwidth equal to the sample rate. */ - step_count = 1 + (freq_max - freq_min - 1) / TUNE_STEP; - freq_max = freq_min + step_count * TUNE_STEP; - if (FREQ_MAX_MHZ MAX_SWEEP_RANGES)){ + return HACKRF_ERROR_INVALID_PARAM; + } + + if(num_samples % SAMPLES_PER_BLOCK) { + return HACKRF_ERROR_INVALID_PARAM; + } + + if(SAMPLES_PER_BLOCK < num_samples) { + return HACKRF_ERROR_INVALID_PARAM; + } + + if(1 > step_width) { + return HACKRF_ERROR_INVALID_PARAM; + } + + if(INTERLEAVED < style) { + return HACKRF_ERROR_INVALID_PARAM; + } + + data[0] = step_width & 0xff; + data[1] = (step_width >> 8) & 0xff; + data[2] = (step_width >> 16) & 0xff; + data[3] = (step_width >> 24) & 0xff; + data[4] = offset & 0xff; + data[5] = (offset >> 8) & 0xff; + data[6] = (offset >> 16) & 0xff; + data[7] = (offset >> 24) & 0xff; + data[8] = style; + for(i=0; i<(num_ranges*2); i++) { + data[9+i*2] = frequency_list[i] & 0xff; + data[10+i*2] = (frequency_list[i] >> 8) & 0xff; + } result = libusb_control_transfer( device->usb_device, LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, HACKRF_VENDOR_REQUEST_INIT_SWEEP, - dwell_time & 0xffff, - (dwell_time >> 16) & 0xffff, - (unsigned char*)frequency_list, + num_samples & 0xffff, + (num_samples >> 16) & 0xffff, + data, size, 0 ); diff --git a/host/libhackrf/src/hackrf.h b/host/libhackrf/src/hackrf.h index 904207e0..a92f5051 100644 --- a/host/libhackrf/src/hackrf.h +++ b/host/libhackrf/src/hackrf.h @@ -47,6 +47,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSI #endif +#define SAMPLES_PER_BLOCK 16384 +#define MAX_SWEEP_RANGES 10 + enum hackrf_error { HACKRF_SUCCESS = 0, HACKRF_TRUE = 1, @@ -95,6 +98,11 @@ enum operacake_ports { OPERACAKE_PB4 = 7, }; +enum sweep_style { + LINEAR = 0, + INTERLEAVED = 1, +}; + typedef struct hackrf_device hackrf_device; typedef struct { @@ -218,10 +226,11 @@ extern ADDAPI uint32_t ADDCALL hackrf_compute_baseband_filter_bw(const uint32_t /* set hardware sync mode */ extern ADDAPI int ADDCALL hackrf_set_hw_sync_mode(hackrf_device* device, const uint8_t value); -/* Start scan mode */ +/* Start sweep mode */ extern ADDAPI int ADDCALL hackrf_init_sweep(hackrf_device* device, - uint16_t* frequency_list, - int length, uint32_t dwell_time); + const uint16_t* frequency_list, const int num_ranges, + const uint32_t num_samples, const uint32_t step_width, + const uint32_t offset, const enum sweep_style style); /* Operacake functions */ extern ADDAPI int ADDCALL hackrf_get_operacake_boards(hackrf_device* device, uint8_t* boards); From 4b6de820efd95b0ee290123ad761692a33184eae Mon Sep 17 00:00:00 2001 From: Michael Ossmann Date: Tue, 7 Feb 2017 15:37:26 -0700 Subject: [PATCH 25/59] support multiple frequency ranges in hackrf_sweep --- firmware/hackrf_usb/usb_api_sweep.h | 2 +- host/hackrf-tools/src/hackrf_sweep.c | 69 ++++++++++++++++++---------- 2 files changed, 45 insertions(+), 26 deletions(-) diff --git a/firmware/hackrf_usb/usb_api_sweep.h b/firmware/hackrf_usb/usb_api_sweep.h index 427c1cb2..20c27859 100644 --- a/firmware/hackrf_usb/usb_api_sweep.h +++ b/firmware/hackrf_usb/usb_api_sweep.h @@ -38,4 +38,4 @@ usb_request_status_t usb_vendor_request_init_sweep( void sweep_mode(void); -#endif /* __USB_API_SPCAN_H__ */ +#endif /* __USB_API_SWEEP_H__ */ diff --git a/host/hackrf-tools/src/hackrf_sweep.c b/host/hackrf-tools/src/hackrf_sweep.c index a5c0489c..4514b5f9 100644 --- a/host/hackrf-tools/src/hackrf_sweep.c +++ b/host/hackrf-tools/src/hackrf_sweep.c @@ -106,6 +106,9 @@ int gettimeofday(struct timeval *tv, void* ignored) { #define sleep(a) Sleep( (a*1000) ) #endif +int num_ranges = 0; +uint16_t frequencies[MAX_SWEEP_RANGES*2]; + static float TimevalDiff(const struct timeval *a, const struct timeval *b) { return (a->tv_sec - b->tv_sec) + 1e-6f * (a->tv_usec - b->tv_usec); } @@ -170,9 +173,6 @@ uint32_t amp_enable; bool antenna = false; uint32_t antenna_enable; -uint32_t freq_min = 10; -uint32_t freq_max = 6000; - bool binary_output = false; int fftSize; @@ -314,9 +314,11 @@ int main(int argc, char** argv) { struct timeval t_end; float time_diff; unsigned int lna_gain=16, vga_gain=20; - uint16_t frequencies[MAX_SWEEP_RANGES*2]; uint32_t num_samples = DEFAULT_SAMPLE_COUNT; int step_count; + uint32_t freq_min = 0; + uint32_t freq_max = 6000; + while( (opt = getopt(argc, argv, "a:f:p:l:g:d:n:Bh?")) != EOF ) { result = HACKRF_SUCCESS; @@ -333,6 +335,29 @@ int main(int argc, char** argv) { case 'f': result = parse_u32_range(optarg, &freq_min, &freq_max); + if(freq_min >= freq_max) { + fprintf(stderr, + "argument error: freq_max must be greater than freq_min.\n"); + usage(); + return EXIT_FAILURE; + } + if(FREQ_MAX_MHZ = freq_max) { - fprintf(stderr, "argument error: freq_max must be greater than freq_min.\n"); - usage(); - return EXIT_FAILURE; - } - - if (FREQ_MAX_MHZ Date: Tue, 7 Feb 2017 16:00:20 -0700 Subject: [PATCH 26/59] fixed firmware bug with sweep ranges that start at high frequencies --- firmware/hackrf_usb/usb_api_sweep.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/firmware/hackrf_usb/usb_api_sweep.c b/firmware/hackrf_usb/usb_api_sweep.c index c1a5f2b4..102bac69 100644 --- a/firmware/hackrf_usb/usb_api_sweep.c +++ b/firmware/hackrf_usb/usb_api_sweep.c @@ -78,7 +78,7 @@ usb_request_status_t usb_vendor_request_init_sweep( for(i=0; i<(num_ranges*2); i++) { frequencies[i] = ((uint16_t)(data[10+i*2]) << 8) + data[9+i*2]; } - sweep_freq = frequencies[0] * FREQ_GRANULARITY; + sweep_freq = (uint64_t)frequencies[0] * FREQ_GRANULARITY; set_freq(sweep_freq + offset); start_sweep_mode = true; usb_transfer_schedule_ack(endpoint->in); @@ -136,7 +136,7 @@ void sweep_mode(void) { if(INTERLEAVED == style) { if(!odd && ((sweep_freq + step_width) >= ((uint64_t)frequencies[1+range*2] * FREQ_GRANULARITY))) { range = (range + 1) % num_ranges; - sweep_freq = frequencies[range*2] * FREQ_GRANULARITY; + sweep_freq = (uint64_t)frequencies[range*2] * FREQ_GRANULARITY; } else { if(odd) { sweep_freq += step_width/4; @@ -148,7 +148,7 @@ void sweep_mode(void) { } else { if((sweep_freq + step_width) >= ((uint64_t)frequencies[1+range*2] * FREQ_GRANULARITY)) { range = (range + 1) % num_ranges; - sweep_freq = frequencies[range*2] * FREQ_GRANULARITY; + sweep_freq = (uint64_t)frequencies[range*2] * FREQ_GRANULARITY; } else { sweep_freq += step_width; } From a32dedf1a795122485054ad6628bec6bb3961ef2 Mon Sep 17 00:00:00 2001 From: Michael Ossmann Date: Tue, 7 Feb 2017 16:18:30 -0700 Subject: [PATCH 27/59] fixed bug in bandwidth filter option error checking in hackrf_transfer --- host/hackrf-tools/src/hackrf_transfer.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/host/hackrf-tools/src/hackrf_transfer.c b/host/hackrf-tools/src/hackrf_transfer.c index 88221716..1d52a54d 100644 --- a/host/hackrf-tools/src/hackrf_transfer.c +++ b/host/hackrf-tools/src/hackrf_transfer.c @@ -807,9 +807,6 @@ int main(int argc, char** argv) { if( baseband_filter_bw ) { - /* Compute nearest freq for bw filter */ - baseband_filter_bw_hz = hackrf_compute_baseband_filter_bw(baseband_filter_bw_hz); - if (baseband_filter_bw_hz > BASEBAND_FILTER_BW_MAX) { fprintf(stderr, "argument error: baseband_filter_bw_hz must be less or equal to %u Hz/%.03f MHz\n", BASEBAND_FILTER_BW_MAX, (float)(BASEBAND_FILTER_BW_MAX/FREQ_ONE_MHZ)); @@ -823,6 +820,9 @@ int main(int argc, char** argv) { usage(); return EXIT_FAILURE; } + + /* Compute nearest freq for bw filter */ + baseband_filter_bw_hz = hackrf_compute_baseband_filter_bw(baseband_filter_bw_hz); } if(requested_mode_count > 1) { From ad9ee61e640ccac119cff65d4ca814856ecb6e5d Mon Sep 17 00:00:00 2001 From: Michael Ossmann Date: Tue, 7 Feb 2017 16:18:30 -0700 Subject: [PATCH 28/59] fixed bug in bandwidth filter option error checking in hackrf_transfer --- host/hackrf-tools/src/hackrf_transfer.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/host/hackrf-tools/src/hackrf_transfer.c b/host/hackrf-tools/src/hackrf_transfer.c index 88221716..1d52a54d 100644 --- a/host/hackrf-tools/src/hackrf_transfer.c +++ b/host/hackrf-tools/src/hackrf_transfer.c @@ -807,9 +807,6 @@ int main(int argc, char** argv) { if( baseband_filter_bw ) { - /* Compute nearest freq for bw filter */ - baseband_filter_bw_hz = hackrf_compute_baseband_filter_bw(baseband_filter_bw_hz); - if (baseband_filter_bw_hz > BASEBAND_FILTER_BW_MAX) { fprintf(stderr, "argument error: baseband_filter_bw_hz must be less or equal to %u Hz/%.03f MHz\n", BASEBAND_FILTER_BW_MAX, (float)(BASEBAND_FILTER_BW_MAX/FREQ_ONE_MHZ)); @@ -823,6 +820,9 @@ int main(int argc, char** argv) { usage(); return EXIT_FAILURE; } + + /* Compute nearest freq for bw filter */ + baseband_filter_bw_hz = hackrf_compute_baseband_filter_bw(baseband_filter_bw_hz); } if(requested_mode_count > 1) { From ebaebf42f82c5de5fc3b9411588dc805cca7d8ba Mon Sep 17 00:00:00 2001 From: Dominic Spill Date: Tue, 7 Feb 2017 14:31:25 -0700 Subject: [PATCH 29/59] Initial commit of combined debug tool --- host/hackrf-tools/src/CMakeLists.txt | 4 +- host/hackrf-tools/src/hackrf_debug.c | 382 +++++++++++++++++++++++++++ 2 files changed, 383 insertions(+), 3 deletions(-) create mode 100644 host/hackrf-tools/src/hackrf_debug.c diff --git a/host/hackrf-tools/src/CMakeLists.txt b/host/hackrf-tools/src/CMakeLists.txt index 00a173fc..2e828d80 100644 --- a/host/hackrf-tools/src/CMakeLists.txt +++ b/host/hackrf-tools/src/CMakeLists.txt @@ -26,14 +26,12 @@ set(INSTALL_DEFAULT_BINDIR "bin" CACHE STRING "Appended to CMAKE_INSTALL_PREFIX" INCLUDE(FindPkgConfig) SET(TOOLS - hackrf_max2837 - hackrf_si5351c hackrf_transfer - hackrf_rffc5071 hackrf_spiflash hackrf_cpldjtag hackrf_info hackrf_operacake + hackrf_debug ) if(MSVC) diff --git a/host/hackrf-tools/src/hackrf_debug.c b/host/hackrf-tools/src/hackrf_debug.c new file mode 100644 index 00000000..350f4f80 --- /dev/null +++ b/host/hackrf-tools/src/hackrf_debug.c @@ -0,0 +1,382 @@ +/* + * Copyright 2012 Jared Boone + * Copyright 2013 Benjamin Vernoux + * Copyright 2017 Dominic Spill + * + * 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 + +#ifndef bool +typedef int bool; +#define true 1 +#define false 0 +#endif + +#define REGISTER_INVALID 32767 + +int parse_int(char* s, uint16_t* const value) { + uint_fast8_t base = 10; + char* s_end; + long long_value; + + if( strlen(s) > 2 ) { + if( s[0] == '0' ) { + if( (s[1] == 'x') || (s[1] == 'X') ) { + base = 16; + s += 2; + } else if( (s[1] == 'b') || (s[1] == 'B') ) { + base = 2; + s += 2; + } + } + } + + s_end = s; + long_value = strtol(s, &s_end, base); + if( (s != s_end) && (*s_end == 0) ) { + *value = (uint16_t)long_value; + return HACKRF_SUCCESS; + } else { + return HACKRF_ERROR_INVALID_PARAM; + } +} + +int max2837_read_register(hackrf_device* device, const uint16_t register_number) { + uint16_t register_value; + int result = hackrf_max2837_read(device, (uint8_t)register_number, ®ister_value); + + if( result == HACKRF_SUCCESS ) { + printf("[%2d] -> 0x%03x\n", register_number, register_value); + } else { + printf("hackrf_max2837_read() failed: %s (%d)\n", hackrf_error_name(result), result); + } + return result; +} + +int max2837_read_registers(hackrf_device* device) { + uint16_t register_number; + int result = HACKRF_SUCCESS; + + for(register_number=0; register_number<32; register_number++) { + result = max2837_read_register(device, register_number); + if( result != HACKRF_SUCCESS ) { + break; + } + } + return result; +} + +int write_max2837_register( + hackrf_device* device, + const uint16_t register_number, + const uint16_t register_value +) { + int result = HACKRF_SUCCESS; + result = hackrf_max2837_write(device, (uint8_t)register_number, register_value); + + if( result == HACKRF_SUCCESS ) { + printf("0x%03x -> [%2d]\n", register_value, register_number); + } else { + printf("hackrf_max2837_write() failed: %s (%d)\n", hackrf_error_name(result), result); + } + return result; +} + +int si5351c_read_register(hackrf_device* device, const uint16_t register_number) { + uint16_t register_value; + int result = hackrf_si5351c_read(device, register_number, ®ister_value); + + if( result == HACKRF_SUCCESS ) { + printf("[%3d] -> 0x%02x\n", register_number, register_value); + } else { + printf("hackrf_si5351c_read() failed: %s (%d)\n", hackrf_error_name(result), result); + } + + return result; +} + +int si5351c_read_registers(hackrf_device* device) { + uint16_t register_number; + int result = HACKRF_SUCCESS; + + for(register_number=0; register_number<256; register_number++) { + result = si5351c_read_register(device, register_number); + if( result != HACKRF_SUCCESS ) { + break; + } + } + + return result; +} + +int si5351c_write_register( + hackrf_device* device, + const uint16_t register_number, + const uint16_t register_value +) { + int result = HACKRF_SUCCESS; + result = hackrf_si5351c_write(device, register_number, register_value); + + if( result == HACKRF_SUCCESS ) { + printf("0x%2x -> [%3d]\n", register_value, register_number); + } else { + printf("hackrf_max2837_write() failed: %s (%d)\n", hackrf_error_name(result), result); + } + + return result; +} + +int si5351c_read_multisynth_config(hackrf_device* device, const uint_fast8_t ms_number) { + uint_fast8_t i; + uint_fast8_t reg_base; + uint16_t parameters[8]; + uint32_t p1,p2,p3,r_div; + uint_fast8_t div_lut[] = {1,2,4,8,16,32,64,128}; + + printf("MS%d:", ms_number); + if(ms_number <6){ + reg_base = 42 + (ms_number * 8); + for(i=0; i<8; i++) { + uint_fast8_t reg_number = reg_base + i; + int result = hackrf_si5351c_read(device, reg_number, ¶meters[i]); + if( result != HACKRF_SUCCESS ) { + return result; + } + } + + p1 = ((parameters[2] & 0x03) << 16) + | (parameters[3] << 8) + | parameters[4]; + p2 = ((parameters[5] & 0x0F) << 16) + | (parameters[6] << 8) + | parameters[7]; + p3 = ((parameters[5] & 0xF0) << 12) + | (parameters[0] << 8) + | parameters[1]; + r_div = (parameters[2] >> 4) & 0x7; + + printf("\tp1 = %u\n", p1); + printf("\tp2 = %u\n", p2); + printf("\tp3 = %u\n", p3); + if(p3) + printf("\tOutput (800Mhz PLL): %#.10f Mhz\n", ((double)800 / (double)(((double)p1*p3 + p2 + 512*p3)/(double)(128*p3))) / div_lut[r_div] ); + } else { + // MS6 and 7 are integer only + unsigned int parms; + reg_base = 90; + + for(i=0; i<3; i++) { + uint_fast8_t reg_number = reg_base + i; + int result = hackrf_si5351c_read(device, reg_number, ¶meters[i]); + if( result != HACKRF_SUCCESS ) { + return result; + } + } + r_div = (ms_number == 6) ? parameters[2] & 0x7 : (parameters[2] & 0x70) >> 4 ; + parms = (ms_number == 6) ? parameters[0] : parameters[1]; + printf("\tp1_int = %u\n", parms); + if(parms) + printf("\tOutput (800Mhz PLL): %#.10f Mhz\n", (800.0f / parms) / div_lut[r_div] ); + } + printf("\toutput divider = %u\n", div_lut[r_div]); + return HACKRF_SUCCESS; +} + +int si5351c_read_configuration(hackrf_device* device) { + uint_fast8_t ms_number; + int result; + + for(ms_number=0; ms_number<8; ms_number++) { + result = si5351c_read_multisynth_config(device, ms_number); + if( result != HACKRF_SUCCESS ) { + return result; + } + } + return HACKRF_SUCCESS; +} + +int rffc5071_read_register(hackrf_device* device, const uint16_t register_number) { + uint16_t register_value; + int result = hackrf_rffc5071_read(device, (uint8_t)register_number, ®ister_value); + + if( result == HACKRF_SUCCESS ) { + printf("[%2d] -> 0x%03x\n", register_number, register_value); + } else { + printf("hackrf_rffc5071_read() failed: %s (%d)\n", hackrf_error_name(result), result); + } + + return result; +} + +int rffc5071_read_registers(hackrf_device* device) { + uint16_t register_number; + int result = HACKRF_SUCCESS; + + for(register_number=0; register_number<31; register_number++) { + result = rffc5071_read_register(device, register_number); + if( result != HACKRF_SUCCESS ) { + break; + } + } + + return result; +} + +int rffc5071_write_register( + hackrf_device* device, + const uint16_t register_number, + const uint16_t register_value +) { + int result = HACKRF_SUCCESS; + result = hackrf_rffc5071_write(device, (uint8_t)register_number, register_value); + + if( result == HACKRF_SUCCESS ) { + printf("0x%03x -> [%2d]\n", register_value, register_number); + } else { + printf("hackrf_rffc5071_write() failed: %s (%d)\n", hackrf_error_name(result), result); + } + + return result; +} + +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 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-d, --device : specify a particular device by serial number\n"); + printf("\nExamples:\n"); + printf("\t -n 12 -r # reads from register 12\n"); + printf("\t -r # reads all registers\n"); + printf("\t -n 10 -w 22 # writes register 10 with 22 decimal\n"); +} + +static struct option long_options[] = { + { "config", no_argument, 0, 'c' }, + { "register", required_argument, 0, 'n' }, + { "write", required_argument, 0, 'w' }, + { "read", no_argument, 0, 'r' }, + { "device", no_argument, 0, 'd' }, + { "help", no_argument, 0, 'h' }, + { 0, 0, 0, 0 }, +}; + +int main(int argc, char** argv) { + int opt; + uint16_t register_number = REGISTER_INVALID; + uint16_t register_value; + hackrf_device* device = NULL; + int option_index = 0; + bool read = false; + bool write = false; + const char* serial_number = NULL; + + int result = hackrf_init(); + if(result) { + printf("hackrf_init() failed: %s (%d)\n", hackrf_error_name(result), result); + return EXIT_FAILURE; + } + + while( (opt = getopt_long(argc, argv, "n:rw:d: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); + break; + + case 'r': + read = true; + break; + + case 'c': + dump_config = true; + break; + + 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; + } + + if(result != HACKRF_SUCCESS) { + printf("argument error: %s (%d)\n", hackrf_error_name(result), result); + 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_by_serial(serial_number, &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 EXIT_FAILURE; + } + + hackrf_exit(); + return EXIT_SUCCESS; +} From 1587c95a59f3e0e9b046ecaaa4baebb932fbd50e Mon Sep 17 00:00:00 2001 From: Dominic Spill Date: Tue, 7 Feb 2017 17:04:47 -0700 Subject: [PATCH 30/59] Support max2837, rffc5071, and si5351 --- host/hackrf-tools/src/hackrf_debug.c | 124 ++++++++++++++++++++++++--- 1 file changed, 112 insertions(+), 12 deletions(-) diff --git a/host/hackrf-tools/src/hackrf_debug.c b/host/hackrf-tools/src/hackrf_debug.c index 350f4f80..e5a14c29 100644 --- a/host/hackrf-tools/src/hackrf_debug.c +++ b/host/hackrf-tools/src/hackrf_debug.c @@ -88,7 +88,7 @@ int max2837_read_registers(hackrf_device* device) { return result; } -int write_max2837_register( +int max2837_write_register( hackrf_device* device, const uint16_t register_number, const uint16_t register_value @@ -261,18 +261,67 @@ int rffc5071_write_register( return result; } +enum parts { + PART_NONE = 0, + PART_MAX2837 = 1, + PART_SI5351C = 2, + PART_RFFC5071 = 3, +}; + +int read_register(hackrf_device* device, uint8_t part, + const uint16_t register_number) { + switch (part) { + case PART_MAX2837: + return max2837_read_register(device, register_number); + case PART_SI5351C: + return si5351c_read_register(device, register_number); + case PART_RFFC5071: + return rffc5071_read_register(device, register_number); + } + return HACKRF_ERROR_INVALID_PARAM; +} + +int read_registers(hackrf_device* device, uint8_t part) { + switch (part) { + case PART_MAX2837: + return max2837_read_registers(device); + case PART_SI5351C: + return si5351c_read_registers(device); + case PART_RFFC5071: + return rffc5071_read_registers(device); + } + return HACKRF_ERROR_INVALID_PARAM; +} + +int write_register(hackrf_device* device, uint8_t part, + const uint16_t register_number, + const uint16_t register_value) { + switch (part) { + case PART_MAX2837: + return max2837_write_register(device, register_number, register_value); + case PART_SI5351C: + return si5351c_write_register(device, register_number, register_value); + case PART_RFFC5071: + return rffc5071_write_register(device, register_number, register_value); + } + return HACKRF_ERROR_INVALID_PARAM; +} + static void usage() { printf("\nUsage:\n"); - printf("\t-h, --help: this help\n"); printf("\t-c, --config: print textual configuration information\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("\t-c, --config: print SI5351C configuration information\n"); printf("\t-d, --device : specify a particular device by serial number\n"); + printf("\t-m, --max2837: target MAX2837\n"); + printf("\t-s, --si5351: target SI5351C\n"); + printf("\t-f, --rffc5071: target RFFC5071\n"); printf("\nExamples:\n"); - printf("\t -n 12 -r # reads from register 12\n"); - printf("\t -r # reads all registers\n"); - printf("\t -n 10 -w 22 # writes register 10 with 22 decimal\n"); + printf("\thackrf_debug -si5351 -n 12 -r # reads from si5351 register 12\n"); + printf("\thackrf_debug -rffc5071 -r # reads all rffc5071 registers\n"); + printf("\thackrf_debug -max2837 -n 10 -w 22 # writes max2837 register 10 with 22 decimal\n"); } static struct option long_options[] = { @@ -282,6 +331,9 @@ static struct option long_options[] = { { "read", no_argument, 0, 'r' }, { "device", no_argument, 0, 'd' }, { "help", no_argument, 0, 'h' }, + { "max2837", no_argument, 0, 'm' }, + { "si5351c", no_argument, 0, 's' }, + { "rffc5071", no_argument, 0, 'f' }, { 0, 0, 0, 0 }, }; @@ -293,6 +345,8 @@ int main(int argc, char** argv) { int option_index = 0; bool read = false; bool write = false; + bool dump_config = false; + uint8_t part = PART_NONE; const char* serial_number = NULL; int result = hackrf_init(); @@ -301,7 +355,7 @@ int main(int argc, char** argv) { return EXIT_FAILURE; } - while( (opt = getopt_long(argc, argv, "n:rw:d:h?", long_options, &option_index)) != EOF ) { + while( (opt = getopt_long(argc, argv, "n:rw:d:cmsfh?", long_options, &option_index)) != EOF ) { switch( opt ) { case 'n': result = parse_int(optarg, ®ister_number); @@ -323,6 +377,30 @@ int main(int argc, char** argv) { case 'd': serial_number = optarg; break; + + case 'm': + if(part != PART_NONE) { + fprintf(stderr, "Only one part can be specified.'\n"); + return EXIT_FAILURE; + } + part = PART_MAX2837; + break; + + case 's': + if(part != PART_NONE) { + fprintf(stderr, "Only one part can be specified.'\n"); + return EXIT_FAILURE; + } + part = PART_SI5351C; + break; + + case 'f': + if(part != PART_NONE) { + fprintf(stderr, "Only one part can be specified.'\n"); + return EXIT_FAILURE; + } + part = PART_RFFC5071; + break; case 'h': case '?': @@ -347,8 +425,26 @@ int main(int argc, char** argv) { return EXIT_FAILURE; } - if(!(write || read)) { - fprintf(stderr, "Specify either read or write option.\n"); + if(write && dump_config) { + fprintf(stderr, "Config and write options are mutually exclusive.\n"); + usage(); + return EXIT_FAILURE; + } + + if(dump_config && part != PART_SI5351C) { + fprintf(stderr, "Config option is only valid for SI5351C.\n"); + usage(); + return EXIT_FAILURE; + } + + if(!(write || read || dump_config)) { + fprintf(stderr, "Specify read, write, or config option.\n"); + usage(); + return EXIT_FAILURE; + } + + if(part == PART_NONE) { + fprintf(stderr, "Specify a part to read, write, or print config from.\n"); usage(); return EXIT_FAILURE; } @@ -360,17 +456,21 @@ int main(int argc, char** argv) { } if(write) { - result = write_register(device, register_number, register_value); + result = write_register(device, part, register_number, register_value); } if(read) { if(register_number == REGISTER_INVALID) { - result = dump_registers(device); + result = read_registers(device, part); } else { - result = dump_register(device, register_number); + result = read_register(device, part, register_number); } } + if(dump_config) { + si5351c_read_configuration(device); + } + result = hackrf_close(device); if(result) { printf("hackrf_close() failed: %s (%d)\n", hackrf_error_name(result), result); From 50da1909f16c1174e6bed164ea25b6b99a974de1 Mon Sep 17 00:00:00 2001 From: Dominic Spill Date: Tue, 7 Feb 2017 17:08:54 -0700 Subject: [PATCH 31/59] Remove old separate debug tools --- host/hackrf-tools/src/hackrf_max2837.c | 236 ----------------- host/hackrf-tools/src/hackrf_rffc5071.c | 233 ----------------- host/hackrf-tools/src/hackrf_si5351c.c | 334 ------------------------ 3 files changed, 803 deletions(-) delete mode 100644 host/hackrf-tools/src/hackrf_max2837.c delete mode 100644 host/hackrf-tools/src/hackrf_rffc5071.c delete mode 100644 host/hackrf-tools/src/hackrf_si5351c.c diff --git a/host/hackrf-tools/src/hackrf_max2837.c b/host/hackrf-tools/src/hackrf_max2837.c deleted file mode 100644 index f64761b3..00000000 --- a/host/hackrf-tools/src/hackrf_max2837.c +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Copyright 2012 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 - -#ifndef bool -typedef int bool; -#define true 1 -#define false 0 -#endif - -static void usage() { - printf("\nUsage:\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("\t-d, --device : specify a particular device by serial number\n"); - printf("\nExamples:\n"); - printf("\t -n 12 -r # reads from register 12\n"); - printf("\t -r # reads all registers\n"); - printf("\t -n 10 -w 22 # writes register 10 with 22 decimal\n"); -} - -static struct option long_options[] = { - { "register", required_argument, 0, 'n' }, - { "write", required_argument, 0, 'w' }, - { "read", no_argument, 0, 'r' }, - { "device", no_argument, 0, 'd' }, - { "help", no_argument, 0, 'h' }, - { 0, 0, 0, 0 }, -}; - -int parse_int(char* s, uint16_t* const value) { - uint_fast8_t base = 10; - char* s_end; - long long_value; - - if( strlen(s) > 2 ) { - if( s[0] == '0' ) { - if( (s[1] == 'x') || (s[1] == 'X') ) { - base = 16; - s += 2; - } else if( (s[1] == 'b') || (s[1] == 'B') ) { - base = 2; - s += 2; - } - } - } - - s_end = s; - long_value = strtol(s, &s_end, base); - if( (s != s_end) && (*s_end == 0) ) { - *value = (uint16_t)long_value; - return HACKRF_SUCCESS; - } else { - return HACKRF_ERROR_INVALID_PARAM; - } -} - -int dump_register(hackrf_device* device, const uint16_t register_number) { - uint16_t register_value; - int result = hackrf_max2837_read(device, (uint8_t)register_number, ®ister_value); - - if( result == HACKRF_SUCCESS ) { - printf("[%2d] -> 0x%03x\n", register_number, register_value); - } else { - printf("hackrf_max2837_read() failed: %s (%d)\n", hackrf_error_name(result), result); - } - - return result; -} - -int dump_registers(hackrf_device* device) { - uint16_t register_number; - int result = HACKRF_SUCCESS; - - for(register_number=0; register_number<32; register_number++) { - result = dump_register(device, register_number); - if( result != HACKRF_SUCCESS ) { - break; - } - } - - return result; -} - -int write_register( - hackrf_device* device, - const uint16_t register_number, - const uint16_t register_value -) { - int result = HACKRF_SUCCESS; - result = hackrf_max2837_write(device, (uint8_t)register_number, register_value); - - if( result == HACKRF_SUCCESS ) { - printf("0x%03x -> [%2d]\n", register_value, register_number); - } else { - printf("hackrf_max2837_write() failed: %s (%d)\n", hackrf_error_name(result), result); - } - - return result; -} - -#define REGISTER_INVALID 32767 - -int main(int argc, char** argv) { - int opt; - uint16_t register_number = REGISTER_INVALID; - uint16_t register_value; - hackrf_device* device = NULL; - int option_index = 0; - bool read = false; - bool write = false; - const char* serial_number = NULL; - - int result = hackrf_init(); - if( result ) { - printf("hackrf_init() failed: %s (%d)\n", hackrf_error_name(result), result); - return EXIT_FAILURE; - } - - while( (opt = getopt_long(argc, argv, "n:rw:d: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); - break; - - case 'r': - read = true; - break; - - 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; - } - - if( result != HACKRF_SUCCESS ) { - printf("argument error: %s (%d)\n", hackrf_error_name(result), result); - 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_by_serial(serial_number, &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(result) { - printf("dump_registers() failed: %s (%d)\n", - hackrf_error_name(result), result); - return EXIT_FAILURE; - } - } - - if(read) { - if(register_number == REGISTER_INVALID) { - result = dump_registers(device); - if(result) { - printf("dump_registers() failed: %s (%d)\n", - hackrf_error_name(result), result); - return EXIT_FAILURE; - } - } - } else { - result = dump_register(device, register_number); - if(result) { - printf("dump_registers() failed: %s (%d)\n", - hackrf_error_name(result), result); - return EXIT_FAILURE; - } - } - - result = hackrf_close(device); - if( result ) { - printf("hackrf_close() failed: %s (%d)\n", hackrf_error_name(result), result); - return EXIT_FAILURE; - } - - hackrf_exit(); - - return EXIT_SUCCESS; -} diff --git a/host/hackrf-tools/src/hackrf_rffc5071.c b/host/hackrf-tools/src/hackrf_rffc5071.c deleted file mode 100644 index f9d478e3..00000000 --- a/host/hackrf-tools/src/hackrf_rffc5071.c +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Copyright 2012 Jared Boone - * Copyright 2013 Benjamin Vernoux - * - * 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 - -#ifndef bool -typedef int bool; -#define true 1 -#define false 0 -#endif - -static void usage() { - printf("\nUsage:\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("\t-d, --device : specify a particular device by serial number\n"); - printf("\nExamples:\n"); - printf("\t -n 12 -r # reads from register 12\n"); - printf("\t -r # reads all registers\n"); - printf("\t -n 10 -w 514 # writes register 10 with 514 decimal\n"); -} - -static struct option long_options[] = { - { "register", required_argument, 0, 'n' }, - { "write", required_argument, 0, 'w' }, - { "read", no_argument, 0, 'r' }, - { "device", no_argument, 0, 'd' }, - { "help", no_argument, 0, 'h' }, - { 0, 0, 0, 0 }, -}; - -int parse_int(char* s, uint16_t* const value) { - uint_fast8_t base = 10; - char* s_end; - long long_value; - - if( strlen(s) > 2 ) { - if( s[0] == '0' ) { - if( (s[1] == 'x') || (s[1] == 'X') ) { - base = 16; - s += 2; - } else if( (s[1] == 'b') || (s[1] == 'B') ) { - base = 2; - s += 2; - } - } - } - - s_end = s; - long_value = strtol(s, &s_end, base); - if( (s != s_end) && (*s_end == 0) ) { - *value = (uint16_t)long_value; - return HACKRF_SUCCESS; - } else { - return HACKRF_ERROR_INVALID_PARAM; - } -} - -int dump_register(hackrf_device* device, const uint16_t register_number) { - uint16_t register_value; - int result = hackrf_rffc5071_read(device, (uint8_t)register_number, ®ister_value); - - if( result == HACKRF_SUCCESS ) { - printf("[%2d] -> 0x%03x\n", register_number, register_value); - } else { - printf("hackrf_rffc5071_read() failed: %s (%d)\n", hackrf_error_name(result), result); - } - - return result; -} - -int dump_registers(hackrf_device* device) { - uint16_t register_number; - int result = HACKRF_SUCCESS; - - for(register_number=0; register_number<31; register_number++) { - result = dump_register(device, register_number); - if( result != HACKRF_SUCCESS ) { - break; - } - } - - return result; -} - -int write_register( - hackrf_device* device, - const uint16_t register_number, - const uint16_t register_value -) { - int result = HACKRF_SUCCESS; - result = hackrf_rffc5071_write(device, (uint8_t)register_number, register_value); - - if( result == HACKRF_SUCCESS ) { - printf("0x%03x -> [%2d]\n", register_value, register_number); - } else { - printf("hackrf_rffc5071_write() failed: %s (%d)\n", hackrf_error_name(result), result); - } - - return result; -} - -#define REGISTER_INVALID 32767 - -int main(int argc, char** argv) { - int opt; - uint16_t register_number = REGISTER_INVALID; - uint16_t register_value; - hackrf_device* device = NULL; - int option_index = 0; - bool read = false; - bool write = false; - const char* serial_number = NULL; - - int result = hackrf_init(); - if( result ) { - printf("hackrf_init() failed: %s (%d)\n", hackrf_error_name(result), result); - return EXIT_FAILURE; - } - - while( (opt = getopt_long(argc, argv, "n:rw:d: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); - break; - case 'r': - read = true; - break; - 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; - } - - if( result != HACKRF_SUCCESS ) { - printf("argument error: %s (%d)\n", hackrf_error_name(result), result); - 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_by_serial(serial_number, &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(result) { - printf("dump_registers() failed: %s (%d)\n", - hackrf_error_name(result), result); - return EXIT_FAILURE; - } - } - - if(read) { - if(register_number == REGISTER_INVALID) { - result = dump_registers(device); - if(result) { - printf("dump_registers() failed: %s (%d)\n", - hackrf_error_name(result), result); - return EXIT_FAILURE; - } - } else { - result = dump_register(device, register_number); - if(result) { - printf("dump_registers() failed: %s (%d)\n", - hackrf_error_name(result), result); - return EXIT_FAILURE; - } - } - } - - result = hackrf_close(device); - if( result ) { - printf("hackrf_close() failed: %s (%d)\n", hackrf_error_name(result), result); - return EXIT_FAILURE; - } - - hackrf_exit(); - - return EXIT_SUCCESS; -} diff --git a/host/hackrf-tools/src/hackrf_si5351c.c b/host/hackrf-tools/src/hackrf_si5351c.c deleted file mode 100644 index 7b01f947..00000000 --- a/host/hackrf-tools/src/hackrf_si5351c.c +++ /dev/null @@ -1,334 +0,0 @@ -/* - * Copyright 2012 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 - -#ifndef bool -typedef int bool; -#define true 1 -#define false 0 -#endif - -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 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-d, --device : specify a particular device by serial number\n"); - printf("\t-D, --device-idx : specify a particular device by number\n"); - printf("\nExamples:\n"); - printf("\t -n 12 -r # reads from register 12\n"); - printf("\t -r # reads all registers\n"); - printf("\t -n 10 -w 22 # writes register 10 with 22 decimal\n"); -} - -static struct option long_options[] = { - { "config", no_argument, 0, 'c' }, - { "register", required_argument, 0, 'n' }, - { "write", required_argument, 0, 'w' }, - { "read", no_argument, 0, 'r' }, - { "device", no_argument, 0, 'd' }, - { "device-idx", no_argument, 0, 'D' }, - { "help", no_argument, 0, 'h' }, - { 0, 0, 0, 0 }, -}; - -int parse_int(char* const s, uint16_t* const value) { - char* s_end = s; - const long long_value = strtol(s, &s_end, 10); - if( (s != s_end) && (*s_end == 0) ) { - *value = (uint16_t)long_value; - return HACKRF_SUCCESS; - } else { - return HACKRF_ERROR_INVALID_PARAM; - } -} - -int dump_register(hackrf_device* device, const uint16_t register_number) { - uint16_t register_value; - int result = hackrf_si5351c_read(device, register_number, ®ister_value); - - if( result == HACKRF_SUCCESS ) { - printf("[%3d] -> 0x%02x\n", register_number, register_value); - } else { - printf("hackrf_max2837_read() failed: %s (%d)\n", hackrf_error_name(result), result); - } - - return result; -} - -int dump_registers(hackrf_device* device) { - uint16_t register_number; - int result = HACKRF_SUCCESS; - - for(register_number=0; register_number<256; register_number++) { - result = dump_register(device, register_number); - if( result != HACKRF_SUCCESS ) { - break; - } - } - - return result; -} - -int write_register( - hackrf_device* device, - const uint16_t register_number, - const uint16_t register_value -) { - int result = HACKRF_SUCCESS; - result = hackrf_si5351c_write(device, register_number, register_value); - - if( result == HACKRF_SUCCESS ) { - printf("0x%2x -> [%3d]\n", register_value, register_number); - } else { - printf("hackrf_max2837_write() failed: %s (%d)\n", hackrf_error_name(result), result); - } - - return result; -} - -#define REGISTER_INVALID 32767 - -int dump_multisynth_config(hackrf_device* device, const uint_fast8_t ms_number) { - uint_fast8_t i; - uint_fast8_t reg_base; - uint16_t parameters[8]; - uint32_t p1,p2,p3,r_div; - uint_fast8_t div_lut[] = {1,2,4,8,16,32,64,128}; - - printf("MS%d:", ms_number); - if(ms_number <6){ - reg_base = 42 + (ms_number * 8); - for(i=0; i<8; i++) { - uint_fast8_t reg_number = reg_base + i; - int result = hackrf_si5351c_read(device, reg_number, ¶meters[i]); - if( result != HACKRF_SUCCESS ) { - return result; - } - } - - p1 = - ((parameters[2] & 0x03) << 16) - | (parameters[3] << 8) - | parameters[4] - ; - p2 = - ((parameters[5] & 0x0F) << 16) - | (parameters[6] << 8) - | parameters[7] - ; - p3 = - ((parameters[5] & 0xF0) << 12) - | (parameters[0] << 8) - | parameters[1] - ; - r_div = - (parameters[2] >> 4) & 0x7 - ; - - printf("\tp1 = %u\n", p1); - printf("\tp2 = %u\n", p2); - printf("\tp3 = %u\n", p3); - if(p3) - printf("\tOutput (800Mhz PLL): %#.10f Mhz\n", ((double)800 / (double)(((double)p1*p3 + p2 + 512*p3)/(double)(128*p3))) / div_lut[r_div] ); - } else { - // MS6 and 7 are integer only - unsigned int parms; - reg_base = 90; - - for(i=0; i<3; i++) { - uint_fast8_t reg_number = reg_base + i; - int result = hackrf_si5351c_read(device, reg_number, ¶meters[i]); - if( result != HACKRF_SUCCESS ) { - return result; - } - } - - r_div = (ms_number == 6) ? parameters[2] & 0x7 : (parameters[2] & 0x70) >> 4 ; - parms = (ms_number == 6) ? parameters[0] : parameters[1]; - printf("\tp1_int = %u\n", parms); - if(parms) - printf("\tOutput (800Mhz PLL): %#.10f Mhz\n", (800.0f / parms) / div_lut[r_div] ); - } - printf("\toutput divider = %u\n", div_lut[r_div]); - - return HACKRF_SUCCESS; -} - -int dump_configuration(hackrf_device* device) { - uint_fast8_t ms_number; - int result; - - for(ms_number=0; ms_number<8; ms_number++) { - result = dump_multisynth_config(device, ms_number); - if( result != HACKRF_SUCCESS ) { - return result; - } - } - - return HACKRF_SUCCESS; -} - -int main(int argc, char** argv) { - int opt; - - uint16_t register_number = REGISTER_INVALID; - uint16_t register_value; - bool read = false; - bool write = false; - bool dump_config = false; - const char* serial_number = NULL; - int device_index = 0; - - hackrf_device* device = NULL; - int option_index = 0; - - int result = hackrf_init(); - if( result ) { - printf("hackrf_init() failed: %s (%d)\n", hackrf_error_name(result), result); - return EXIT_FAILURE; - } - - while( (opt = getopt_long(argc, argv, "d:D:cn: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); - break; - - case 'r': - read = true; - break; - - case 'c': - dump_config = true; - break; - - case 'D': - device_index = atoi(optarg); - break; - - 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; - } - - if( result != HACKRF_SUCCESS ) { - printf("argument error: %s (%d)\n", hackrf_error_name(result), result); - break; - } - } - - 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 { - hackrf_device_list_t* device_list = hackrf_device_list(); - if(device_list->devicecount <= 0) { - result = HACKRF_ERROR_NOT_FOUND; - } else { - result = hackrf_device_list_open(device_list, device_index, &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(result) { - printf("dump_registers() failed: %s (%d)\n", - hackrf_error_name(result), result); - return EXIT_FAILURE; - } - } - - if(read) { - if( register_number == REGISTER_INVALID ) { - result = dump_registers(device); - if(result) { - printf("dump_registers() failed: %s (%d)\n", - hackrf_error_name(result), result); - return EXIT_FAILURE; - } - } else { - result = dump_register(device, register_number); - if(result) { - printf("dump_registers() failed: %s (%d)\n", - hackrf_error_name(result), result); - return EXIT_FAILURE; - } - } - } - - if(dump_config) { - dump_configuration(device); - } - - result = hackrf_close(device); - if(result) { - printf("hackrf_close() failed: %s (%d)\n", hackrf_error_name(result), result); - return EXIT_FAILURE; - } - - hackrf_exit(); - - return EXIT_SUCCESS; -} From 0c45d65dc3fc7bc1952f4b99cd03f39365d33cec Mon Sep 17 00:00:00 2001 From: Michael Ossmann Date: Tue, 7 Feb 2017 17:12:16 -0700 Subject: [PATCH 32/59] allow selection of FFT bin width in hackrf_sweep --- host/hackrf-tools/src/hackrf_sweep.c | 47 +++++++++++++++++++++------- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/host/hackrf-tools/src/hackrf_sweep.c b/host/hackrf-tools/src/hackrf_sweep.c index 4514b5f9..4627b8b0 100644 --- a/host/hackrf-tools/src/hackrf_sweep.c +++ b/host/hackrf-tools/src/hackrf_sweep.c @@ -99,8 +99,6 @@ int gettimeofday(struct timeval *tv, void* ignored) { #define DEFAULT_SAMPLE_COUNT 0x4000 #define BLOCKS_PER_TRANSFER 16 -#define FFT_BIN_WIDTH_HZ 312500 -#define FFT_SIZE 64 #if defined _WIN32 #define sleep(a) Sleep( (a*1000) ) @@ -175,7 +173,8 @@ uint32_t antenna_enable; bool binary_output = false; -int fftSize; +int fftSize = 20; +uint32_t fft_bin_width; fftwf_complex *fftwIn = NULL; fftwf_complex *fftwOut = NULL; fftwf_plan fftwPlan = NULL; @@ -250,9 +249,9 @@ int rx_callback(hackrf_transfer* transfer) { time_str, (uint64_t)(frequency), (uint64_t)(frequency+DEFAULT_SAMPLE_RATE_HZ/4), - (float)FFT_BIN_WIDTH_HZ, - FFT_SIZE); - for(i=fftSize/8; (fftSize*3)/8 > i; i++) { + (float)fft_bin_width, + fftSize); + for(i=1+fftSize/8; (1+(fftSize*3)/8) > i; i++) { printf(", %.2f", pwr[i]); } printf("\n"); @@ -260,9 +259,9 @@ int rx_callback(hackrf_transfer* transfer) { time_str, (uint64_t)(frequency+(DEFAULT_SAMPLE_RATE_HZ/2)), (uint64_t)(frequency+((DEFAULT_SAMPLE_RATE_HZ*3)/4)), - (float)FFT_BIN_WIDTH_HZ, - FFT_SIZE); - for(i=(fftSize*5)/8; (fftSize*7)/8 > i; i++) { + (float)fft_bin_width, + fftSize); + for(i=1+(fftSize*5)/8; (1+(fftSize*7)/8) > i; i++) { printf(", %.2f", pwr[i]); } printf("\n"); @@ -284,6 +283,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[-n num_samples] # Number of samples per frequency, 16384-4294967296\n"); + fprintf(stderr, "\t[-w bin_width] # FFT bin width (frequency resolution) in Hz\n"); fprintf(stderr, "\t[-B] # binary output\n"); } @@ -320,7 +320,7 @@ int main(int argc, char** argv) { uint32_t freq_max = 6000; - while( (opt = getopt(argc, argv, "a:f:p:l:g:d:n:Bh?")) != EOF ) { + while( (opt = getopt(argc, argv, "a:f:p:l:g:d:n:w:Bh?")) != EOF ) { result = HACKRF_SUCCESS; switch( opt ) { @@ -377,6 +377,11 @@ int main(int argc, char** argv) { result = parse_u32(optarg, &num_samples); break; + case 'w': + result = parse_u32(optarg, &fft_bin_width); + fftSize = DEFAULT_SAMPLE_RATE_HZ / fft_bin_width; + break; + case 'B': binary_output = true; break; @@ -437,7 +442,27 @@ int main(int argc, char** argv) { num_ranges++; } - fftSize = FFT_SIZE; + if(4 > fftSize) { + fprintf(stderr, + "argument error: FFT bin width (-w) must be no more than one quarter the sample rate\n"); + return EXIT_FAILURE; + } + + if(65536 < fftSize) { + fprintf(stderr, + "argument error: FFT bin width (-w) resulted in more than 65536 FFT bins\n"); + return EXIT_FAILURE; + } + + /* In interleaved mode, the FFT bin selection works best if the total + * number of FFT bins is equal to an odd multiple of four. + * (e.g. 4, 12, 20, 28, 36, . . .) + */ + while((fftSize + 4) % 8) { + fftSize++; + } + + fft_bin_width = DEFAULT_SAMPLE_RATE_HZ / fftSize; fftwIn = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex) * fftSize); fftwOut = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex) * fftSize); fftwPlan = fftwf_plan_dft_1d(fftSize, fftwIn, fftwOut, FFTW_FORWARD, FFTW_MEASURE); From 813f540e94100e5be3b80a72703fb6fb5ac2adea Mon Sep 17 00:00:00 2001 From: Michael Ossmann Date: Tue, 7 Feb 2017 17:48:24 -0700 Subject: [PATCH 33/59] fixed FFT bin reordering bug in hackrf_sweep --- host/hackrf-tools/src/hackrf_sweep.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/host/hackrf-tools/src/hackrf_sweep.c b/host/hackrf-tools/src/hackrf_sweep.c index 4627b8b0..d1707896 100644 --- a/host/hackrf-tools/src/hackrf_sweep.c +++ b/host/hackrf-tools/src/hackrf_sweep.c @@ -230,11 +230,7 @@ int rx_callback(hackrf_transfer* transfer) { buf += fftSize * 2; fftwf_execute(fftwPlan); for (i=0; i < fftSize; i++) { - // Start from the middle of the FFTW array and wrap - // to rearrange the data - //FIXME only works when fftSize = 2**n - int k = i ^ (fftSize >> 1); - pwr[i] = logPower(fftwOut[k], 1.0f / fftSize); + pwr[i] = logPower(fftwOut[i], 1.0f / fftSize); } if(binary_output) { float_freq = frequency; @@ -251,7 +247,7 @@ int rx_callback(hackrf_transfer* transfer) { (uint64_t)(frequency+DEFAULT_SAMPLE_RATE_HZ/4), (float)fft_bin_width, fftSize); - for(i=1+fftSize/8; (1+(fftSize*3)/8) > i; i++) { + for(i=1+(fftSize*5)/8; (1+(fftSize*7)/8) > i; i++) { printf(", %.2f", pwr[i]); } printf("\n"); @@ -261,7 +257,7 @@ int rx_callback(hackrf_transfer* transfer) { (uint64_t)(frequency+((DEFAULT_SAMPLE_RATE_HZ*3)/4)), (float)fft_bin_width, fftSize); - for(i=1+(fftSize*5)/8; (1+(fftSize*7)/8) > i; i++) { + for(i=1+fftSize/8; (1+(fftSize*3)/8) > i; i++) { printf(", %.2f", pwr[i]); } printf("\n"); From 00d5b1c5754b6872810dffb33ff3d4792d2dce79 Mon Sep 17 00:00:00 2001 From: Michael Ossmann Date: Tue, 7 Feb 2017 17:52:09 -0700 Subject: [PATCH 34/59] don't send first buffer to host in sweep mode until it is full --- firmware/hackrf_usb/usb_api_sweep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/hackrf_usb/usb_api_sweep.c b/firmware/hackrf_usb/usb_api_sweep.c index 102bac69..0c0b06fa 100644 --- a/firmware/hackrf_usb/usb_api_sweep.c +++ b/firmware/hackrf_usb/usb_api_sweep.c @@ -88,7 +88,7 @@ usb_request_status_t usb_vendor_request_init_sweep( void sweep_mode(void) { unsigned int blocks_queued = 0; - unsigned int phase = 0; + unsigned int phase = 1; uint8_t *buffer; bool transfer = false; From 05759ce1c8f879e9d032da01ecdc03025746b39c Mon Sep 17 00:00:00 2001 From: Michael Ossmann Date: Tue, 7 Feb 2017 18:02:52 -0700 Subject: [PATCH 35/59] fft bin selection in hackrf_sweep binary output, similar to text output --- host/hackrf-tools/src/hackrf_sweep.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/host/hackrf-tools/src/hackrf_sweep.c b/host/hackrf-tools/src/hackrf_sweep.c index d1707896..91cf5cf6 100644 --- a/host/hackrf-tools/src/hackrf_sweep.c +++ b/host/hackrf-tools/src/hackrf_sweep.c @@ -233,10 +233,14 @@ int rx_callback(hackrf_transfer* transfer) { pwr[i] = logPower(fftwOut[i], 1.0f / fftSize); } if(binary_output) { - float_freq = frequency; + float_freq = frequency + DEFAULT_SAMPLE_RATE_HZ / 4; float_freq /= FREQ_ONE_MHZ; fwrite(&float_freq, sizeof(float), 1, stdout); - fwrite(pwr, sizeof(float), fftSize, stdout); + fwrite(&pwr[1+(fftSize*5)/8], sizeof(float), fftSize/4, stdout); + float_freq = frequency + DEFAULT_SAMPLE_RATE_HZ / 2; + float_freq /= FREQ_ONE_MHZ; + fwrite(&float_freq, sizeof(float), 1, stdout); + fwrite(&pwr[1+fftSize/8], sizeof(float), fftSize/4, stdout); } else { time_now = time(NULL); fft_time = localtime(&time_now); From c68aedef314dd0cbf9b112e1073211ffe9236d6a Mon Sep 17 00:00:00 2001 From: Michael Ossmann Date: Tue, 7 Feb 2017 20:25:21 -0700 Subject: [PATCH 36/59] added output description to hackrf_sweep help --- host/hackrf-tools/src/hackrf_sweep.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/host/hackrf-tools/src/hackrf_sweep.c b/host/hackrf-tools/src/hackrf_sweep.c index 91cf5cf6..dfc66954 100644 --- a/host/hackrf-tools/src/hackrf_sweep.c +++ b/host/hackrf-tools/src/hackrf_sweep.c @@ -276,15 +276,18 @@ 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 RF amplifier 1=Enable, 0=Disable.\n"); - fprintf(stderr, "\t[-f freq_min:freq_max] # Specify minimum & maximum sweep frequencies (MHz).\n"); - fprintf(stderr, "\t[-p antenna_enable] # Antenna port power, 1=Enable, 0=Disable.\n"); + fprintf(stderr, "\t[-d serial_number] # Serial number of desired HackRF\n"); + fprintf(stderr, "\t[-a amp_enable] # RX RF amplifier 1=Enable, 0=Disable\n"); + fprintf(stderr, "\t[-f freq_min:freq_max] # minimum and maximum frequencies in MHz\n"); + fprintf(stderr, "\t[-p antenna_enable] # Antenna port power, 1=Enable, 0=Disable\n"); 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[-n num_samples] # Number of samples per frequency, 16384-4294967296\n"); fprintf(stderr, "\t[-w bin_width] # FFT bin width (frequency resolution) in Hz\n"); fprintf(stderr, "\t[-B] # binary output\n"); + fprintf(stderr, "\n"); + fprintf(stderr, "Output fields:\n"); + fprintf(stderr, "\tdate, time, hz_low, hz_high, hz_bin_width, num_samples, dB, dB, . . .\n"); } static hackrf_device* device = NULL; From 5ab315a73acb5d48e71ffa4dd2ed73b3e00311d8 Mon Sep 17 00:00:00 2001 From: Michael Ossmann Date: Tue, 7 Feb 2017 21:11:50 -0700 Subject: [PATCH 37/59] code cleanup --- host/hackrf-tools/src/hackrf_sweep.c | 136 +++++++++++++-------------- 1 file changed, 66 insertions(+), 70 deletions(-) diff --git a/host/hackrf-tools/src/hackrf_sweep.c b/host/hackrf-tools/src/hackrf_sweep.c index dfc66954..40bdb6eb 100644 --- a/host/hackrf-tools/src/hackrf_sweep.c +++ b/host/hackrf-tools/src/hackrf_sweep.c @@ -1,6 +1,7 @@ /* * Copyright 2016 Dominic Spill * Copyright 2016 Mike Walters + * Copyright 2017 Michael Ossmann * * This file is part of HackRF. * @@ -193,84 +194,79 @@ float logPower(fftwf_complex in, float scale) } int rx_callback(hackrf_transfer* transfer) { - /* This is where we need to do interesting things with the samples - * FFT - * Throw away unused bins - * write output to pipe - */ int8_t* buf; uint8_t* ubuf; uint64_t frequency; /* in Hz */ float float_freq; int i, j; - if( fd != NULL ) { - byte_count += transfer->valid_length; - buf = (int8_t*) transfer->buffer; - for(j=0; j i; i++) { - printf(", %.2f", pwr[i]); - } - printf("\n"); - printf("%s, %" PRIu64 ", %" PRIu64 ", %.2f, %u", - time_str, - (uint64_t)(frequency+(DEFAULT_SAMPLE_RATE_HZ/2)), - (uint64_t)(frequency+((DEFAULT_SAMPLE_RATE_HZ*3)/4)), - (float)fft_bin_width, - fftSize); - for(i=1+fftSize/8; (1+(fftSize*3)/8) > i; i++) { - printf(", %.2f", pwr[i]); - } - printf("\n"); - } - } - return 0; - } else { + if(NULL == fd) { return -1; } + + byte_count += transfer->valid_length; + buf = (int8_t*) transfer->buffer; + for(j=0; j i; i++) { + printf(", %.2f", pwr[i]); + } + printf("\n"); + printf("%s, %" PRIu64 ", %" PRIu64 ", %.2f, %u", + time_str, + (uint64_t)(frequency+(DEFAULT_SAMPLE_RATE_HZ/2)), + (uint64_t)(frequency+((DEFAULT_SAMPLE_RATE_HZ*3)/4)), + (float)fft_bin_width, + fftSize); + for(i=1+fftSize/8; (1+(fftSize*3)/8) > i; i++) { + printf(", %.2f", pwr[i]); + } + printf("\n"); + } + } + return 0; } static void usage() { From 5e6e70659bf520af56d09053c88efecfc07ab072 Mon Sep 17 00:00:00 2001 From: Michael Ossmann Date: Wed, 8 Feb 2017 00:37:42 -0700 Subject: [PATCH 38/59] hackrf_sweep: suppress processing and output until the first expected frequency is seen --- host/hackrf-tools/src/hackrf_sweep.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/host/hackrf-tools/src/hackrf_sweep.c b/host/hackrf-tools/src/hackrf_sweep.c index 40bdb6eb..de08f7e2 100644 --- a/host/hackrf-tools/src/hackrf_sweep.c +++ b/host/hackrf-tools/src/hackrf_sweep.c @@ -173,6 +173,7 @@ bool antenna = false; uint32_t antenna_enable; bool binary_output = false; +volatile bool sweep_started = false; int fftSize = 20; uint32_t fft_bin_width; @@ -216,6 +217,14 @@ int rx_callback(hackrf_transfer* transfer) { buf += SAMPLES_PER_BLOCK; break; } + if(!sweep_started) { + if (frequency == (uint64_t)(FREQ_ONE_MHZ*frequencies[0])) { + sweep_started = true; + } else { + buf += SAMPLES_PER_BLOCK; + continue; + } + } if((FREQ_MAX_MHZ * FREQ_ONE_MHZ) < frequency) { buf += SAMPLES_PER_BLOCK; break; From c9c70f7adb8fcaebb06f9ccc0adfc1e7cd89b783 Mon Sep 17 00:00:00 2001 From: Michael Ossmann Date: Wed, 8 Feb 2017 00:42:13 -0700 Subject: [PATCH 39/59] hackrf_sweep: don't skip more input than necessary when waiting for valid data --- host/hackrf-tools/src/hackrf_sweep.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/host/hackrf-tools/src/hackrf_sweep.c b/host/hackrf-tools/src/hackrf_sweep.c index de08f7e2..1947a36a 100644 --- a/host/hackrf-tools/src/hackrf_sweep.c +++ b/host/hackrf-tools/src/hackrf_sweep.c @@ -215,7 +215,7 @@ int rx_callback(hackrf_transfer* transfer) { | ((uint64_t)(ubuf[3]) << 8) | ubuf[2]; } else { buf += SAMPLES_PER_BLOCK; - break; + continue; } if(!sweep_started) { if (frequency == (uint64_t)(FREQ_ONE_MHZ*frequencies[0])) { @@ -227,7 +227,7 @@ int rx_callback(hackrf_transfer* transfer) { } if((FREQ_MAX_MHZ * FREQ_ONE_MHZ) < frequency) { buf += SAMPLES_PER_BLOCK; - break; + continue; } /* copy to fftwIn as floats */ buf += SAMPLES_PER_BLOCK - (fftSize * 2); From 5b881e1d5451b860fcc0db392ed9ff0a1e2c7e72 Mon Sep 17 00:00:00 2001 From: Michael Ossmann Date: Wed, 8 Feb 2017 10:44:16 -0700 Subject: [PATCH 40/59] fixed bug that caused tuning glitches in interleaved sweep mode --- firmware/hackrf_usb/usb_api_sweep.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/firmware/hackrf_usb/usb_api_sweep.c b/firmware/hackrf_usb/usb_api_sweep.c index 0c0b06fa..35656e81 100644 --- a/firmware/hackrf_usb/usb_api_sweep.c +++ b/firmware/hackrf_usb/usb_api_sweep.c @@ -36,7 +36,6 @@ volatile bool start_sweep_mode = false; static uint64_t sweep_freq; -static bool odd = true; static uint16_t frequencies[MAX_RANGES * 2]; static unsigned char data[9 + MAX_RANGES * 2 * sizeof(frequencies[0])]; static uint16_t num_ranges = 0; @@ -44,7 +43,6 @@ static uint32_t dwell_blocks = 0; static uint32_t step_width = 0; static uint32_t offset = 0; static enum sweep_style style = LINEAR; -static uint16_t range = 0; usb_request_status_t usb_vendor_request_init_sweep( usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) @@ -89,6 +87,8 @@ usb_request_status_t usb_vendor_request_init_sweep( void sweep_mode(void) { unsigned int blocks_queued = 0; unsigned int phase = 1; + bool odd = true; + uint16_t range = 0; uint8_t *buffer; bool transfer = false; From 03d93c1369a64718cd5c89b422bde72537c8564e Mon Sep 17 00:00:00 2001 From: Michael Ossmann Date: Wed, 8 Feb 2017 10:46:08 -0700 Subject: [PATCH 41/59] added one shot mode to hackrf_sweep --- host/hackrf-tools/src/hackrf_sweep.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/host/hackrf-tools/src/hackrf_sweep.c b/host/hackrf-tools/src/hackrf_sweep.c index 1947a36a..2edd68cf 100644 --- a/host/hackrf-tools/src/hackrf_sweep.c +++ b/host/hackrf-tools/src/hackrf_sweep.c @@ -173,6 +173,7 @@ bool antenna = false; uint32_t antenna_enable; bool binary_output = false; +bool one_shot = false; volatile bool sweep_started = false; int fftSize = 20; @@ -208,6 +209,9 @@ int rx_callback(hackrf_transfer* transfer) { byte_count += transfer->valid_length; buf = (int8_t*) transfer->buffer; for(j=0; j= (uint64_t)(FREQ_ONE_MHZ*frequencies[num_ranges*2-1]))) { + do_exit = true; + } } return 0; } @@ -289,6 +297,7 @@ static void usage() { fprintf(stderr, "\t[-g gain_db] # RX VGA (baseband) gain, 0-62dB, 2dB steps\n"); fprintf(stderr, "\t[-n num_samples] # Number of samples per frequency, 16384-4294967296\n"); fprintf(stderr, "\t[-w bin_width] # FFT bin width (frequency resolution) in Hz\n"); + fprintf(stderr, "\t[-1] # one shot mode\n"); fprintf(stderr, "\t[-B] # binary output\n"); fprintf(stderr, "\n"); fprintf(stderr, "Output fields:\n"); @@ -328,7 +337,7 @@ int main(int argc, char** argv) { uint32_t freq_max = 6000; - while( (opt = getopt(argc, argv, "a:f:p:l:g:d:n:w:Bh?")) != EOF ) { + while( (opt = getopt(argc, argv, "a:f:p:l:g:d:n:w:1Bh?")) != EOF ) { result = HACKRF_SUCCESS; switch( opt ) { @@ -390,6 +399,10 @@ int main(int argc, char** argv) { fftSize = DEFAULT_SAMPLE_RATE_HZ / fft_bin_width; break; + case '1': + one_shot = true; + break; + case 'B': binary_output = true; break; @@ -456,9 +469,9 @@ int main(int argc, char** argv) { return EXIT_FAILURE; } - if(65536 < fftSize) { + if(16368 < fftSize) { fprintf(stderr, - "argument error: FFT bin width (-w) resulted in more than 65536 FFT bins\n"); + "argument error: FFT bin width (-w) too small, resulted in more than 16368 FFT bins\n"); return EXIT_FAILURE; } From 77ace5a1186f0a7ef29f322f8dc627b7aa66daf6 Mon Sep 17 00:00:00 2001 From: Michael Ossmann Date: Wed, 8 Feb 2017 14:35:25 -0700 Subject: [PATCH 42/59] made part naming consistent in hackrf_debug --- host/hackrf-tools/src/hackrf_debug.c | 41 ++++++++++++++++------------ 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/host/hackrf-tools/src/hackrf_debug.c b/host/hackrf-tools/src/hackrf_debug.c index e5a14c29..52c30eb6 100644 --- a/host/hackrf-tools/src/hackrf_debug.c +++ b/host/hackrf-tools/src/hackrf_debug.c @@ -217,7 +217,14 @@ int si5351c_read_configuration(hackrf_device* device) { return HACKRF_SUCCESS; } -int rffc5071_read_register(hackrf_device* device, const uint16_t register_number) { +/* + * RFFC5071 and RFFC5072 are similar components with a compatible control + * interface. RFFC5071 was used on some early prototypes, so the libhackrf API + * calls are named that way. Because we use RFFC5072 on production hardware, + * we use that name here and present it to the user. + */ + +int rffc5072_read_register(hackrf_device* device, const uint16_t register_number) { uint16_t register_value; int result = hackrf_rffc5071_read(device, (uint8_t)register_number, ®ister_value); @@ -230,12 +237,12 @@ int rffc5071_read_register(hackrf_device* device, const uint16_t register_number return result; } -int rffc5071_read_registers(hackrf_device* device) { +int rffc5072_read_registers(hackrf_device* device) { uint16_t register_number; int result = HACKRF_SUCCESS; for(register_number=0; register_number<31; register_number++) { - result = rffc5071_read_register(device, register_number); + result = rffc5072_read_register(device, register_number); if( result != HACKRF_SUCCESS ) { break; } @@ -244,7 +251,7 @@ int rffc5071_read_registers(hackrf_device* device) { return result; } -int rffc5071_write_register( +int rffc5072_write_register( hackrf_device* device, const uint16_t register_number, const uint16_t register_value @@ -265,7 +272,7 @@ enum parts { PART_NONE = 0, PART_MAX2837 = 1, PART_SI5351C = 2, - PART_RFFC5071 = 3, + PART_RFFC5072 = 3, }; int read_register(hackrf_device* device, uint8_t part, @@ -275,8 +282,8 @@ int read_register(hackrf_device* device, uint8_t part, return max2837_read_register(device, register_number); case PART_SI5351C: return si5351c_read_register(device, register_number); - case PART_RFFC5071: - return rffc5071_read_register(device, register_number); + case PART_RFFC5072: + return rffc5072_read_register(device, register_number); } return HACKRF_ERROR_INVALID_PARAM; } @@ -287,8 +294,8 @@ int read_registers(hackrf_device* device, uint8_t part) { return max2837_read_registers(device); case PART_SI5351C: return si5351c_read_registers(device); - case PART_RFFC5071: - return rffc5071_read_registers(device); + case PART_RFFC5072: + return rffc5072_read_registers(device); } return HACKRF_ERROR_INVALID_PARAM; } @@ -301,8 +308,8 @@ int write_register(hackrf_device* device, uint8_t part, return max2837_write_register(device, register_number, register_value); case PART_SI5351C: return si5351c_write_register(device, register_number, register_value); - case PART_RFFC5071: - return rffc5071_write_register(device, register_number, register_value); + case PART_RFFC5072: + return rffc5072_write_register(device, register_number, register_value); } return HACKRF_ERROR_INVALID_PARAM; } @@ -316,11 +323,11 @@ static void usage() { printf("\t-c, --config: print SI5351C configuration information\n"); printf("\t-d, --device : specify a particular device by serial number\n"); printf("\t-m, --max2837: target MAX2837\n"); - printf("\t-s, --si5351: target SI5351C\n"); - printf("\t-f, --rffc5071: target RFFC5071\n"); + printf("\t-s, --si5351c: target SI5351C\n"); + printf("\t-f, --rffc5072: target RFFC5072\n"); printf("\nExamples:\n"); - printf("\thackrf_debug -si5351 -n 12 -r # reads from si5351 register 12\n"); - printf("\thackrf_debug -rffc5071 -r # reads all rffc5071 registers\n"); + printf("\thackrf_debug -si5351c -n 12 -r # reads from si5351c register 12\n"); + printf("\thackrf_debug -rffc5072 -r # reads all rffc5072 registers\n"); printf("\thackrf_debug -max2837 -n 10 -w 22 # writes max2837 register 10 with 22 decimal\n"); } @@ -333,7 +340,7 @@ static struct option long_options[] = { { "help", no_argument, 0, 'h' }, { "max2837", no_argument, 0, 'm' }, { "si5351c", no_argument, 0, 's' }, - { "rffc5071", no_argument, 0, 'f' }, + { "rffc5072", no_argument, 0, 'f' }, { 0, 0, 0, 0 }, }; @@ -399,7 +406,7 @@ int main(int argc, char** argv) { fprintf(stderr, "Only one part can be specified.'\n"); return EXIT_FAILURE; } - part = PART_RFFC5071; + part = PART_RFFC5072; break; case 'h': From b6d2774a0b9dc85728f309566991a8847b85af58 Mon Sep 17 00:00:00 2001 From: Michael Ossmann Date: Wed, 8 Feb 2017 14:37:01 -0700 Subject: [PATCH 43/59] fixed long option usage examples --- host/hackrf-tools/src/hackrf_debug.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/host/hackrf-tools/src/hackrf_debug.c b/host/hackrf-tools/src/hackrf_debug.c index 52c30eb6..e48ddd77 100644 --- a/host/hackrf-tools/src/hackrf_debug.c +++ b/host/hackrf-tools/src/hackrf_debug.c @@ -326,9 +326,9 @@ static void usage() { printf("\t-s, --si5351c: target SI5351C\n"); printf("\t-f, --rffc5072: target RFFC5072\n"); printf("\nExamples:\n"); - printf("\thackrf_debug -si5351c -n 12 -r # reads from si5351c register 12\n"); - printf("\thackrf_debug -rffc5072 -r # reads all rffc5072 registers\n"); - printf("\thackrf_debug -max2837 -n 10 -w 22 # writes max2837 register 10 with 22 decimal\n"); + printf("\thackrf_debug --si5351c -n 12 -r # reads from si5351c register 12\n"); + printf("\thackrf_debug --rffc5072 -r # reads all rffc5072 registers\n"); + printf("\thackrf_debug --max2837 -n 10 -w 22 # writes max2837 register 10 with 22 decimal\n"); } static struct option long_options[] = { From f2877d20af6f77b38abc4c3d634014455435a449 Mon Sep 17 00:00:00 2001 From: Michael Ossmann Date: Wed, 8 Feb 2017 14:38:23 -0700 Subject: [PATCH 44/59] change si5351c usage example to be the most common register that folks are likely to want to read --- host/hackrf-tools/src/hackrf_debug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/host/hackrf-tools/src/hackrf_debug.c b/host/hackrf-tools/src/hackrf_debug.c index e48ddd77..fcd0f42e 100644 --- a/host/hackrf-tools/src/hackrf_debug.c +++ b/host/hackrf-tools/src/hackrf_debug.c @@ -326,7 +326,7 @@ static void usage() { printf("\t-s, --si5351c: target SI5351C\n"); printf("\t-f, --rffc5072: target RFFC5072\n"); printf("\nExamples:\n"); - printf("\thackrf_debug --si5351c -n 12 -r # reads from si5351c register 12\n"); + printf("\thackrf_debug --si5351c -n 0 -r # reads from si5351c register 0\n"); printf("\thackrf_debug --rffc5072 -r # reads all rffc5072 registers\n"); printf("\thackrf_debug --max2837 -n 10 -w 22 # writes max2837 register 10 with 22 decimal\n"); } From 405a11fb96f0d0c3312987adc34ac2882aac373c Mon Sep 17 00:00:00 2001 From: Michael Ossmann Date: Wed, 8 Feb 2017 14:41:48 -0700 Subject: [PATCH 45/59] added multisynth config to hackrf_debug example usage --- host/hackrf-tools/src/hackrf_debug.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/host/hackrf-tools/src/hackrf_debug.c b/host/hackrf-tools/src/hackrf_debug.c index fcd0f42e..8155477c 100644 --- a/host/hackrf-tools/src/hackrf_debug.c +++ b/host/hackrf-tools/src/hackrf_debug.c @@ -320,13 +320,14 @@ static void usage() { 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-c, --config: print SI5351C configuration information\n"); + printf("\t-c, --config: print SI5351C multisynth configuration information\n"); printf("\t-d, --device : specify a particular device by serial number\n"); printf("\t-m, --max2837: target MAX2837\n"); printf("\t-s, --si5351c: target SI5351C\n"); printf("\t-f, --rffc5072: target RFFC5072\n"); printf("\nExamples:\n"); printf("\thackrf_debug --si5351c -n 0 -r # reads from si5351c register 0\n"); + printf("\thackrf_debug --si5351c -c # displays si5351c multisynth configuration\n"); printf("\thackrf_debug --rffc5072 -r # reads all rffc5072 registers\n"); printf("\thackrf_debug --max2837 -n 10 -w 22 # writes max2837 register 10 with 22 decimal\n"); } From 9e4f14443afac36628e751ebf12984c3fb957059 Mon Sep 17 00:00:00 2001 From: Michael Ossmann Date: Wed, 8 Feb 2017 14:48:52 -0700 Subject: [PATCH 46/59] Don't build hackrf_operacake utility. Operacake developers can reverse this change locally if needed. The utility will have a new name or will be replaced by functions in other tools before we reinstate it. --- host/hackrf-tools/src/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/host/hackrf-tools/src/CMakeLists.txt b/host/hackrf-tools/src/CMakeLists.txt index 2e828d80..d9938846 100644 --- a/host/hackrf-tools/src/CMakeLists.txt +++ b/host/hackrf-tools/src/CMakeLists.txt @@ -30,7 +30,6 @@ SET(TOOLS hackrf_spiflash hackrf_cpldjtag hackrf_info - hackrf_operacake hackrf_debug ) From 53d0b8b73ee3771c78fcd84741e7ed0fa7d76ee2 Mon Sep 17 00:00:00 2001 From: Michael Ossmann Date: Wed, 8 Feb 2017 15:44:21 -0700 Subject: [PATCH 47/59] set release string in libhackrf and hackrf-tools even if they are built separately --- host/CMakeLists.txt | 27 --------------------------- host/cmake/set_release.cmake | 26 ++++++++++++++++++++++++++ host/hackrf-tools/CMakeLists.txt | 1 + host/libhackrf/CMakeLists.txt | 1 + 4 files changed, 28 insertions(+), 27 deletions(-) create mode 100644 host/cmake/set_release.cmake diff --git a/host/CMakeLists.txt b/host/CMakeLists.txt index 69b0ef31..874163f8 100644 --- a/host/CMakeLists.txt +++ b/host/CMakeLists.txt @@ -3,33 +3,6 @@ cmake_minimum_required(VERSION 2.8) project (hackrf_all) -#set(RELEASE "") - -if(NOT DEFINED RELEASE) - execute_process( - COMMAND git log -n 1 --format=%h - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - RESULT_VARIABLE GIT_EXIT_VALUE - ERROR_QUIET - OUTPUT_VARIABLE GIT_VERSION - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - if (GIT_EXIT_VALUE) - set(RELEASE "unknown") - else (GIT_EXIT_VALUE) - execute_process( - COMMAND git status -s --untracked-files=no - OUTPUT_VARIABLE DIRTY - ) - if ( NOT "${DIRTY}" STREQUAL "" ) - set(DIRTY_FLAG "*") - else() - set(DIRTY_FLAG "") - endif() - set(RELEASE "git-${GIT_VERSION}${DIRTY_FLAG}") - endif (GIT_EXIT_VALUE) -endif() - add_subdirectory(libhackrf) add_subdirectory(hackrf-tools) diff --git a/host/cmake/set_release.cmake b/host/cmake/set_release.cmake new file mode 100644 index 00000000..875808f9 --- /dev/null +++ b/host/cmake/set_release.cmake @@ -0,0 +1,26 @@ +#set(RELEASE "") + +if(NOT DEFINED RELEASE) + execute_process( + COMMAND git log -n 1 --format=%h + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + RESULT_VARIABLE GIT_EXIT_VALUE + ERROR_QUIET + OUTPUT_VARIABLE GIT_VERSION + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + if (GIT_EXIT_VALUE) + set(RELEASE "unknown") + else (GIT_EXIT_VALUE) + execute_process( + COMMAND git status -s --untracked-files=no + OUTPUT_VARIABLE DIRTY + ) + if ( NOT "${DIRTY}" STREQUAL "" ) + set(DIRTY_FLAG "*") + else() + set(DIRTY_FLAG "") + endif() + set(RELEASE "git-${GIT_VERSION}${DIRTY_FLAG}") + endif (GIT_EXIT_VALUE) +endif() diff --git a/host/hackrf-tools/CMakeLists.txt b/host/hackrf-tools/CMakeLists.txt index 18dbf007..fd9f83be 100644 --- a/host/hackrf-tools/CMakeLists.txt +++ b/host/hackrf-tools/CMakeLists.txt @@ -24,6 +24,7 @@ cmake_minimum_required(VERSION 2.8) project(hackrf-tools C) set(PACKAGE hackrf-tools) +include(${PROJECT_SOURCE_DIR}/../cmake/set_release.cmake) add_definitions(-DTOOL_RELEASE="${RELEASE}") set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/../cmake/modules) diff --git a/host/libhackrf/CMakeLists.txt b/host/libhackrf/CMakeLists.txt index c3cd4946..08168941 100644 --- a/host/libhackrf/CMakeLists.txt +++ b/host/libhackrf/CMakeLists.txt @@ -29,6 +29,7 @@ set(PACKAGE libhackrf) set(VERSION_STRING ${MAJOR_VERSION}.${MINOR_VERSION}) set(VERSION ${VERSION_STRING}) add_definitions(-DLIBRARY_VERSION="${VERSION_STRING}") +include(${PROJECT_SOURCE_DIR}/../cmake/set_release.cmake) add_definitions(-DLIBRARY_RELEASE="${RELEASE}") set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/../cmake/modules) From 4ac132a4ea0339732cda9ee4905b6b94b3c06408 Mon Sep 17 00:00:00 2001 From: Michael Ossmann Date: Wed, 8 Feb 2017 17:03:05 -0700 Subject: [PATCH 48/59] hackrf_transfer: switched some output messages from stdout to stderr --- host/hackrf-tools/src/hackrf_transfer.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/host/hackrf-tools/src/hackrf_transfer.c b/host/hackrf-tools/src/hackrf_transfer.c index 1d52a54d..f90a1a92 100644 --- a/host/hackrf-tools/src/hackrf_transfer.c +++ b/host/hackrf-tools/src/hackrf_transfer.c @@ -434,7 +434,7 @@ int tx_callback(hackrf_transfer* transfer) { } if (bytes_read != bytes_to_read) { if (repeat) { - printf("Input file end reached. Rewind to beginning.\n"); + fprintf(stderr, "Input file end reached. Rewind to beginning.\n"); rewind(fd); fread(transfer->buffer + bytes_read, 1, bytes_to_read - bytes_read, fd); return 0; @@ -1056,14 +1056,14 @@ int main(int argc, char** argv) { len=stream_size-stream_head; bytes_written = fwrite(stream_buf+stream_head, 1, len, fd); if (len != bytes_written) { - printf("write failed"); + fprintf(stderr, "write failed"); do_exit=true; }; stream_head=(stream_head+len)%stream_size; } if(stream_drop>0) { uint32_t drops= __atomic_exchange_n (&stream_drop,0,__ATOMIC_SEQ_CST); - printf("dropped frames: [%d]\n",drops); + fprintf(stderr, "dropped frames: [%d]\n", drops); } #endif } else { From e7647f62f357301d3cf98a87e23f24b7c00f94c6 Mon Sep 17 00:00:00 2001 From: Michael Ossmann Date: Wed, 8 Feb 2017 17:24:05 -0700 Subject: [PATCH 49/59] fixed bug in frequency reported to binary output of hackrf_sweep --- host/hackrf-tools/src/hackrf_sweep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/host/hackrf-tools/src/hackrf_sweep.c b/host/hackrf-tools/src/hackrf_sweep.c index 2edd68cf..ea482a21 100644 --- a/host/hackrf-tools/src/hackrf_sweep.c +++ b/host/hackrf-tools/src/hackrf_sweep.c @@ -245,7 +245,7 @@ int rx_callback(hackrf_transfer* transfer) { pwr[i] = logPower(fftwOut[i], 1.0f / fftSize); } if(binary_output) { - float_freq = frequency + DEFAULT_SAMPLE_RATE_HZ / 4; + float_freq = frequency; float_freq /= FREQ_ONE_MHZ; fwrite(&float_freq, sizeof(float), 1, stdout); fwrite(&pwr[1+(fftSize*5)/8], sizeof(float), fftSize/4, stdout); From 3de6d2d360ce7c992844e830f9f33c1bf68c1da8 Mon Sep 17 00:00:00 2001 From: Dominic Spill Date: Thu, 9 Feb 2017 16:34:57 -0700 Subject: [PATCH 50/59] Disable EMC clock --- firmware/common/hackrf_core.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/firmware/common/hackrf_core.c b/firmware/common/hackrf_core.c index d71b9f53..cc07d054 100644 --- a/firmware/common/hackrf_core.c +++ b/firmware/common/hackrf_core.c @@ -35,6 +35,7 @@ #include "i2c_bus.h" #include "i2c_lpc.h" #include +#include #include #include @@ -554,6 +555,10 @@ void cpu_clock_init(void) /* use IRC as clock source for APB3 */ CGU_BASE_APB3_CLK = CGU_BASE_APB3_CLK_CLK_SEL(CGU_SRC_IRC); + /* Disable unused peripheral clocks */ + CCU1_CLK_M4_EMC_CFG = 0; + CCU1_CLK_M4_EMCDIV_CFG = 0; + i2c_bus_start(clock_gen.bus, &i2c_config_si5351c_slow_clock); si5351c_disable_all_outputs(&clock_gen); @@ -829,10 +834,6 @@ void pin_setup(void) { scu_pinmux(SCU_PINMUX_EN1V8, SCU_GPIO_NOPULL); - /* Disable unused clock outputs. They generate noise. */ - scu_pinmux(CLK0, SCU_CLK_IN | SCU_CONF_FUNCTION7); - scu_pinmux(CLK2, SCU_CLK_IN | SCU_CONF_FUNCTION7); - /* Configure USB indicators */ #if (defined JELLYBEAN || defined JAWBREAKER) scu_pinmux(SCU_PINMUX_USB_LED0, SCU_CONF_FUNCTION3); From a1d6e7b3febec2c54834859e99bede8aba929985 Mon Sep 17 00:00:00 2001 From: Dominic Spill Date: Thu, 9 Feb 2017 16:35:56 -0700 Subject: [PATCH 51/59] Modify hw sync mode to require an argument - allows it to be ignored for HackRFs with older firmware --- host/hackrf-tools/src/hackrf_transfer.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/host/hackrf-tools/src/hackrf_transfer.c b/host/hackrf-tools/src/hackrf_transfer.c index f90a1a92..d263d83e 100644 --- a/host/hackrf-tools/src/hackrf_transfer.c +++ b/host/hackrf-tools/src/hackrf_transfer.c @@ -311,6 +311,7 @@ bool signalsource = false; uint32_t amplitude = 0; bool hw_sync = false; +uint32_t hw_sync_enable; bool receive = false; bool receive_wav = false; @@ -503,7 +504,7 @@ static void usage() { printf("\t[-R] # Repeat TX mode (default is off) \n"); printf("\t[-b baseband_filter_bw_hz] # Set baseband filter bandwidth in Hz.\n\tPossible values: 1.75/2.5/3.5/5/5.5/6/7/8/9/10/12/14/15/20/24/28MHz, default <= 0.75 * sample_rate_hz.\n" ); printf("\t[-C ppm] # Set Internal crystal clock error in ppm.\n"); - printf("\t[-H] # Synchronise USB transfer using GPIO pins.\n"); + printf("\t[-H hw_sync_enable] # Synchronise USB transfer using GPIO pins.\n"); } static hackrf_device* device = NULL; @@ -547,13 +548,14 @@ 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:h?")) != EOF ) + while( (opt = getopt(argc, argv, "H:wr:t:f:i:o:m:a:p:s:n:b:l:g:x:c:d:C:RS:h?")) != EOF ) { result = HACKRF_SUCCESS; switch( opt ) { case 'H': hw_sync = true; + result = parse_u32(optarg, &hw_sync_enable); break; case 'w': receive_wav = true; @@ -961,11 +963,13 @@ int main(int argc, char** argv) { } } - 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); - return EXIT_FAILURE; + if(hw_sync) { + fprintf(stderr, "call hackrf_set_hw_sync_mode(%d)\n", hw_sync); + result = hackrf_set_hw_sync_mode(device, hw_sync_enable ? 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); + return EXIT_FAILURE; + } } if( transceiver_mode == TRANSCEIVER_MODE_RX ) { From 06e24e876f141ba107571b6b92dfcbf9c91376ec Mon Sep 17 00:00:00 2001 From: Michael Ossmann Date: Thu, 9 Feb 2017 17:32:33 -0700 Subject: [PATCH 52/59] added fields to hackrf_sweep binary output --- host/hackrf-tools/src/hackrf_sweep.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/host/hackrf-tools/src/hackrf_sweep.c b/host/hackrf-tools/src/hackrf_sweep.c index ea482a21..68251e60 100644 --- a/host/hackrf-tools/src/hackrf_sweep.c +++ b/host/hackrf-tools/src/hackrf_sweep.c @@ -199,7 +199,8 @@ int rx_callback(hackrf_transfer* transfer) { int8_t* buf; uint8_t* ubuf; uint64_t frequency; /* in Hz */ - float float_freq; + uint64_t band_edge; + uint32_t record_length; int i, j; if(NULL == fd) { @@ -245,13 +246,23 @@ int rx_callback(hackrf_transfer* transfer) { pwr[i] = logPower(fftwOut[i], 1.0f / fftSize); } if(binary_output) { - float_freq = frequency; - float_freq /= FREQ_ONE_MHZ; - fwrite(&float_freq, sizeof(float), 1, stdout); + record_length = 2 * sizeof(band_edge) + sizeof(fft_bin_width) + + (fftSize/4) * sizeof(float); + + fwrite(&record_length, sizeof(record_length), 1, stdout); + band_edge = frequency; + fwrite(&band_edge, sizeof(band_edge), 1, stdout); + band_edge = frequency + DEFAULT_SAMPLE_RATE_HZ / 4; + fwrite(&band_edge, sizeof(band_edge), 1, stdout); + fwrite(&fft_bin_width, sizeof(fft_bin_width), 1, stdout); fwrite(&pwr[1+(fftSize*5)/8], sizeof(float), fftSize/4, stdout); - float_freq = frequency + DEFAULT_SAMPLE_RATE_HZ / 2; - float_freq /= FREQ_ONE_MHZ; - fwrite(&float_freq, sizeof(float), 1, stdout); + + fwrite(&record_length, sizeof(record_length), 1, stdout); + band_edge = frequency + DEFAULT_SAMPLE_RATE_HZ / 2; + fwrite(&band_edge, sizeof(band_edge), 1, stdout); + band_edge = frequency + (DEFAULT_SAMPLE_RATE_HZ * 3) / 4; + fwrite(&band_edge, sizeof(band_edge), 1, stdout); + fwrite(&fft_bin_width, sizeof(fft_bin_width), 1, stdout); fwrite(&pwr[1+fftSize/8], sizeof(float), fftSize/4, stdout); } else { time_now = time(NULL); From 2163ebac9c49627692e6a4b1cf99972bab415ba7 Mon Sep 17 00:00:00 2001 From: Dominic Spill Date: Thu, 9 Feb 2017 21:23:58 -0700 Subject: [PATCH 53/59] Power down or disable all clocks that we aren't using --- firmware/common/hackrf_core.c | 71 +++++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 4 deletions(-) diff --git a/firmware/common/hackrf_core.c b/firmware/common/hackrf_core.c index cc07d054..9c4f9d52 100644 --- a/firmware/common/hackrf_core.c +++ b/firmware/common/hackrf_core.c @@ -555,10 +555,6 @@ void cpu_clock_init(void) /* use IRC as clock source for APB3 */ CGU_BASE_APB3_CLK = CGU_BASE_APB3_CLK_CLK_SEL(CGU_SRC_IRC); - /* Disable unused peripheral clocks */ - CCU1_CLK_M4_EMC_CFG = 0; - CCU1_CLK_M4_EMCDIV_CFG = 0; - i2c_bus_start(clock_gen.bus, &i2c_config_si5351c_slow_clock); si5351c_disable_all_outputs(&clock_gen); @@ -712,6 +708,73 @@ void cpu_clock_init(void) CGU_BASE_SSP1_CLK = CGU_BASE_SSP1_CLK_AUTOBLOCK(1) | CGU_BASE_SSP1_CLK_CLK_SEL(CGU_SRC_PLL1); + + /* Disable unused clocks */ + /* Start with PLLs */ + CGU_PLL0AUDIO_CTRL = CGU_PLL0AUDIO_CTRL_PD(1); + + /* Dividers */ + CGU_IDIVA_CTRL = CGU_IDIVA_CTRL_PD(1); + CGU_IDIVB_CTRL = CGU_IDIVB_CTRL_PD(1); + CGU_IDIVC_CTRL = CGU_IDIVC_CTRL_PD(1); + CGU_IDIVD_CTRL = CGU_IDIVD_CTRL_PD(1); + CGU_IDIVE_CTRL = CGU_IDIVE_CTRL_PD(1); + + /* Base clocks */ + CGU_BASE_SPIFI_CLK = CGU_BASE_SPIFI_CLK_PD(1); /* SPIFI is only used at boot */ + CGU_BASE_USB1_CLK = CGU_BASE_USB1_CLK_PD(1); /* USB1 is not exposed on HackRF */ + CGU_BASE_PHY_RX_CLK = CGU_BASE_PHY_RX_CLK_PD(1); + CGU_BASE_PHY_TX_CLK = CGU_BASE_PHY_TX_CLK_PD(1); + CGU_BASE_LCD_CLK = CGU_BASE_LCD_CLK_PD(1); + CGU_BASE_VADC_CLK = CGU_BASE_VADC_CLK_PD(1); + CGU_BASE_SDIO_CLK = CGU_BASE_SDIO_CLK_PD(1); + CGU_BASE_UART0_CLK = CGU_BASE_UART0_CLK_PD(1); + CGU_BASE_UART1_CLK = CGU_BASE_UART1_CLK_PD(1); + CGU_BASE_UART2_CLK = CGU_BASE_UART2_CLK_PD(1); + CGU_BASE_UART3_CLK = CGU_BASE_UART3_CLK_PD(1); + CGU_BASE_OUT_CLK = CGU_BASE_OUT_CLK_PD(1); + CGU_BASE_AUDIO_CLK = CGU_BASE_AUDIO_CLK_PD(1); + CGU_BASE_CGU_OUT0_CLK = CGU_BASE_CGU_OUT0_CLK_PD(1); + CGU_BASE_CGU_OUT1_CLK = CGU_BASE_CGU_OUT1_CLK_PD(1); + + /* Disable unused peripheral clocks */ + CCU1_CLK_APB1_CAN1_CFG = 0; + CCU1_CLK_APB1_I2S_CFG = 0; + CCU1_CLK_APB1_MOTOCONPWM_CFG = 0; + CCU1_CLK_APB3_ADC0_CFG = 0; + CCU1_CLK_APB3_ADC1_CFG = 0; + CCU1_CLK_APB3_CAN0_CFG = 0; + CCU1_CLK_APB3_DAC_CFG = 0; + CCU1_CLK_M4_DMA_CFG = 0; + CCU1_CLK_M4_EMC_CFG = 0; + CCU1_CLK_M4_EMCDIV_CFG = 0; + CCU1_CLK_M4_ETHERNET_CFG = 0; + CCU1_CLK_M4_GPIO_CFG = 0; + CCU1_CLK_M4_LCD_CFG = 0; + CCU1_CLK_M4_QEI_CFG = 0; + CCU1_CLK_M4_RITIMER_CFG = 0; + CCU1_CLK_M4_SCT_CFG = 0; + CCU1_CLK_M4_SDIO_CFG = 0; + CCU1_CLK_M4_SPIFI_CFG = 0; + CCU1_CLK_M4_TIMER0_CFG = 0; + CCU1_CLK_M4_TIMER1_CFG = 0; + CCU1_CLK_M4_TIMER2_CFG = 0; + CCU1_CLK_M4_TIMER3_CFG = 0; + CCU1_CLK_M4_UART1_CFG = 0; + CCU1_CLK_M4_USART0_CFG = 0; + CCU1_CLK_M4_USART2_CFG = 0; + CCU1_CLK_M4_USART3_CFG = 0; + CCU1_CLK_M4_USB1_CFG = 0; + CCU1_CLK_M4_VADC_CFG = 0; + CCU1_CLK_SPIFI_CFG = 0; + CCU1_CLK_USB1_CFG = 0; + CCU1_CLK_VADC_CFG = 0; + CCU2_CLK_APB0_UART1_CFG = 0; + CCU2_CLK_APB0_USART0_CFG = 0; + CCU2_CLK_APB2_USART2_CFG = 0; + CCU2_CLK_APB2_USART3_CFG = 0; + CCU2_CLK_APLL_CFG = 0; + CCU2_CLK_SDIO_CFG = 0; } From 2936ff3cef3d78ce51a633b0b8834685c30ee542 Mon Sep 17 00:00:00 2001 From: Michael Ossmann Date: Thu, 9 Feb 2017 22:16:26 -0700 Subject: [PATCH 54/59] clarified some things in firmware/README --- firmware/README | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/firmware/README b/firmware/README index 94cccc9f..e6087c2c 100644 --- a/firmware/README +++ b/firmware/README @@ -27,22 +27,27 @@ To build and install a standard firmware image for HackRF One: $ cd hackrf_usb $ mkdir build $ cd build -$ cmake .. -DBOARD=HACKRF_ONE +$ cmake .. $ make $ hackrf_spiflash -w hackrf_usb.bin -If you have a Jawbreaker, use -DBOARD=JAWBREAKER instead. +If you have a Jawbreaker, add -DBOARD=JAWBREAKER to the cmake command. -For loading firmware into RAM with DFU you will also need: +It is possible to use a USB Device Firmware Upgrade (DFU) method to load +firmware into RAM. This is normally only required to recover a device that has +had faulty firmware loaded, but it can also be useful for firmware developers. -http://dfu-util.gnumonks.org/ +For loading firmware into RAM with DFU you will need: + +http://dfu-util.sourceforge.net/ To start up HackRF One in DFU mode, hold down the DFU button while powering it on or while pressing and releasing the RESET button. Release the DFU button after the 3V3 LED illuminates. A .dfu file is built by default when building firmware. Alternatively you can -load a known good .dfu file from a release package with: +use a known good .dfu file from a release package. Load the firmware into RAM +with: $ dfu-util --device 1fc9:000c --alt 0 --download hackrf_usb.dfu From 55e3a2087d21da68459c7330f871486dda946936 Mon Sep 17 00:00:00 2001 From: Michael Ossmann Date: Thu, 9 Feb 2017 23:52:07 -0700 Subject: [PATCH 55/59] hackrf_sweep: fftwf_free --- host/hackrf-tools/src/hackrf_sweep.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/host/hackrf-tools/src/hackrf_sweep.c b/host/hackrf-tools/src/hackrf_sweep.c index 68251e60..1967a105 100644 --- a/host/hackrf-tools/src/hackrf_sweep.c +++ b/host/hackrf-tools/src/hackrf_sweep.c @@ -680,6 +680,10 @@ int main(int argc, char** argv) { fd = NULL; fprintf(stderr, "fclose(fd) done\n"); } + fftwf_free(fftwIn); + fftwf_free(fftwOut); + fftwf_free(pwr); + fftwf_free(window); fprintf(stderr, "exit\n"); return exit_code; } From c0396ea2fb0558bfd2a23bbcfd5994b6adc7b843 Mon Sep 17 00:00:00 2001 From: Dominic Spill Date: Fri, 10 Feb 2017 10:29:54 -0700 Subject: [PATCH 56/59] Reenable some clocks so that HackRF boots --- firmware/common/hackrf_core.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/firmware/common/hackrf_core.c b/firmware/common/hackrf_core.c index 9c4f9d52..545b57e5 100644 --- a/firmware/common/hackrf_core.c +++ b/firmware/common/hackrf_core.c @@ -749,7 +749,6 @@ void cpu_clock_init(void) CCU1_CLK_M4_EMC_CFG = 0; CCU1_CLK_M4_EMCDIV_CFG = 0; CCU1_CLK_M4_ETHERNET_CFG = 0; - CCU1_CLK_M4_GPIO_CFG = 0; CCU1_CLK_M4_LCD_CFG = 0; CCU1_CLK_M4_QEI_CFG = 0; CCU1_CLK_M4_RITIMER_CFG = 0; @@ -766,15 +765,15 @@ void cpu_clock_init(void) CCU1_CLK_M4_USART3_CFG = 0; CCU1_CLK_M4_USB1_CFG = 0; CCU1_CLK_M4_VADC_CFG = 0; - CCU1_CLK_SPIFI_CFG = 0; - CCU1_CLK_USB1_CFG = 0; - CCU1_CLK_VADC_CFG = 0; - CCU2_CLK_APB0_UART1_CFG = 0; - CCU2_CLK_APB0_USART0_CFG = 0; - CCU2_CLK_APB2_USART2_CFG = 0; - CCU2_CLK_APB2_USART3_CFG = 0; - CCU2_CLK_APLL_CFG = 0; - CCU2_CLK_SDIO_CFG = 0; + // CCU1_CLK_SPIFI_CFG = 0; + // CCU1_CLK_USB1_CFG = 0; + // CCU1_CLK_VADC_CFG = 0; + // CCU2_CLK_APB0_UART1_CFG = 0; + // CCU2_CLK_APB0_USART0_CFG = 0; + // CCU2_CLK_APB2_USART2_CFG = 0; + // CCU2_CLK_APB2_USART3_CFG = 0; + // CCU2_CLK_APLL_CFG = 0; + // CCU2_CLK_SDIO_CFG = 0; } From c57066ebf83c3d749d4d55e23f8be2f5b78c6325 Mon Sep 17 00:00:00 2001 From: Michael Ossmann Date: Fri, 10 Feb 2017 16:37:52 -0700 Subject: [PATCH 57/59] hackrf_sweep: removed bin width from binary output because a more precise result can be computed from the number of bins in a record --- host/hackrf-tools/src/hackrf_sweep.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/host/hackrf-tools/src/hackrf_sweep.c b/host/hackrf-tools/src/hackrf_sweep.c index 1967a105..5f7fd823 100644 --- a/host/hackrf-tools/src/hackrf_sweep.c +++ b/host/hackrf-tools/src/hackrf_sweep.c @@ -246,7 +246,7 @@ int rx_callback(hackrf_transfer* transfer) { pwr[i] = logPower(fftwOut[i], 1.0f / fftSize); } if(binary_output) { - record_length = 2 * sizeof(band_edge) + sizeof(fft_bin_width) + record_length = 2 * sizeof(band_edge) + (fftSize/4) * sizeof(float); fwrite(&record_length, sizeof(record_length), 1, stdout); @@ -254,7 +254,6 @@ int rx_callback(hackrf_transfer* transfer) { fwrite(&band_edge, sizeof(band_edge), 1, stdout); band_edge = frequency + DEFAULT_SAMPLE_RATE_HZ / 4; fwrite(&band_edge, sizeof(band_edge), 1, stdout); - fwrite(&fft_bin_width, sizeof(fft_bin_width), 1, stdout); fwrite(&pwr[1+(fftSize*5)/8], sizeof(float), fftSize/4, stdout); fwrite(&record_length, sizeof(record_length), 1, stdout); @@ -262,7 +261,6 @@ int rx_callback(hackrf_transfer* transfer) { fwrite(&band_edge, sizeof(band_edge), 1, stdout); band_edge = frequency + (DEFAULT_SAMPLE_RATE_HZ * 3) / 4; fwrite(&band_edge, sizeof(band_edge), 1, stdout); - fwrite(&fft_bin_width, sizeof(fft_bin_width), 1, stdout); fwrite(&pwr[1+fftSize/8], sizeof(float), fftSize/4, stdout); } else { time_now = time(NULL); From e6351d7d69525348a69252b4238a27c8d81c9fa9 Mon Sep 17 00:00:00 2001 From: Michael Ossmann Date: Fri, 10 Feb 2017 22:39:25 -0700 Subject: [PATCH 58/59] fixed bug that prevented use of num_samples argument to hackrf_init_sweep() --- host/libhackrf/src/hackrf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/host/libhackrf/src/hackrf.c b/host/libhackrf/src/hackrf.c index 61de081d..151f4e8e 100644 --- a/host/libhackrf/src/hackrf.c +++ b/host/libhackrf/src/hackrf.c @@ -1841,7 +1841,7 @@ int ADDCALL hackrf_init_sweep(hackrf_device* device, return HACKRF_ERROR_INVALID_PARAM; } - if(SAMPLES_PER_BLOCK < num_samples) { + if(SAMPLES_PER_BLOCK > num_samples) { return HACKRF_ERROR_INVALID_PARAM; } From 0dee1e3b0f351786b53cacda063dfe5692c17385 Mon Sep 17 00:00:00 2001 From: Michael Ossmann Date: Fri, 10 Feb 2017 22:58:31 -0700 Subject: [PATCH 59/59] updated top level readme --- Readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Readme.md b/Readme.md index 8d244481..5da2bb8c 100644 --- a/Readme.md +++ b/Readme.md @@ -1,5 +1,5 @@ -This repository contains hardware designs and software for HackRF, a project to -produce a low cost, open source software radio platform. +This repository contains hardware designs and software for HackRF, +a low cost, open source Software Defined Radio platform. ![HackRF One](https://raw.github.com/mossmann/hackrf/master/doc/HackRF-One-fd0-0009.jpeg)