From b047dd0cb44c6125698aebe0dc9bf1ddb7ea4350 Mon Sep 17 00:00:00 2001 From: Dominic Spill Date: Fri, 27 Jan 2017 15:03:53 -0700 Subject: [PATCH 1/3] Add software controlled reset --- firmware/hackrf_usb/hackrf_usb.c | 3 +- firmware/hackrf_usb/usb_api_board_info.c | 11 ++++++ firmware/hackrf_usb/usb_api_board_info.h | 2 + firmware/libopencm3 | 2 +- host/hackrf-tools/src/hackrf_spiflash.c | 50 ++++++++++++++++-------- host/libhackrf/src/hackrf.c | 20 ++++++++++ host/libhackrf/src/hackrf.h | 2 + 7 files changed, 72 insertions(+), 18 deletions(-) diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index c82bf179..2e7cf8f9 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -80,7 +80,8 @@ static const usb_request_handler_fn vendor_request_handler[] = { usb_vendor_request_init_sweep, usb_vendor_request_operacake_get_boards, usb_vendor_request_operacake_set_ports, - usb_vendor_request_set_hw_sync_mode + usb_vendor_request_set_hw_sync_mode, + usb_vendor_request_reset }; static const uint32_t vendor_request_handler_count = diff --git a/firmware/hackrf_usb/usb_api_board_info.c b/firmware/hackrf_usb/usb_api_board_info.c index 7cad222f..ba2a6ddd 100644 --- a/firmware/hackrf_usb/usb_api_board_info.c +++ b/firmware/hackrf_usb/usb_api_board_info.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -91,3 +92,13 @@ usb_request_status_t usb_vendor_request_read_partid_serialno( } return USB_REQUEST_STATUS_OK; } + +usb_request_status_t usb_vendor_request_reset( + usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) +{ + if (stage == USB_TRANSFER_STAGE_SETUP) { + wwdt_reset(100000); + usb_transfer_schedule_ack(endpoint->in); + } + return USB_REQUEST_STATUS_OK; +} \ No newline at end of file diff --git a/firmware/hackrf_usb/usb_api_board_info.h b/firmware/hackrf_usb/usb_api_board_info.h index 90a76cb9..39824b8d 100644 --- a/firmware/hackrf_usb/usb_api_board_info.h +++ b/firmware/hackrf_usb/usb_api_board_info.h @@ -39,5 +39,7 @@ usb_request_status_t usb_vendor_request_read_version_string( usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); usb_request_status_t usb_vendor_request_read_partid_serialno( usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); +usb_request_status_t usb_vendor_request_reset( + usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); #endif /* end of include guard: __USB_API_BOARD_INFO_H__ */ diff --git a/firmware/libopencm3 b/firmware/libopencm3 index 0ca89139..d3d6f3e7 160000 --- a/firmware/libopencm3 +++ b/firmware/libopencm3 @@ -1 +1 @@ -Subproject commit 0ca89139446586e743b842fb1074db0f2173f6dd +Subproject commit d3d6f3e74b34593d1b56175abe5b4cb72da4ec9d diff --git a/host/hackrf-tools/src/hackrf_spiflash.c b/host/hackrf-tools/src/hackrf_spiflash.c index 20a50d3f..bb5c53bb 100644 --- a/host/hackrf-tools/src/hackrf_spiflash.c +++ b/host/hackrf-tools/src/hackrf_spiflash.c @@ -91,6 +91,7 @@ static void usage() printf("\t-r : Read data into file.\n"); printf("\t-w : Write data from file.\n"); printf("\t-d : Serial number of device, if multiple devices\n"); + printf("\t-R: Reset HackRF after other operations.\n"); printf("\t-v: Verbose output.\n"); } @@ -112,8 +113,9 @@ int main(int argc, char** argv) bool read = false; bool write = false; bool verbose = false; + bool reset = false; - while ((opt = getopt_long(argc, argv, "a:l:r:w:d:v", long_options, + while ((opt = getopt_long(argc, argv, "a:l:r:w:d:vR", long_options, &option_index)) != EOF) { switch (opt) { case 'a': @@ -142,6 +144,10 @@ int main(int argc, char** argv) verbose = true; break; + case 'R': + reset = true; + break; + default: fprintf(stderr, "opt error: %d\n", opt); usage(); @@ -156,17 +162,17 @@ int main(int argc, char** argv) } } - if (write == read) { - if (write == true) { + if((write == read) && (write == reset)) { + if(write && read) { fprintf(stderr, "Read and write options are mutually exclusive.\n"); } else { - fprintf(stderr, "Specify either read or write option.\n"); + fprintf(stderr, "Specify either read, write, or reset option.\n"); } usage(); return EXIT_FAILURE; } - if (path == NULL) { + if((read || write) && (path == NULL)) { fprintf(stderr, "Specify a path to a file.\n"); usage(); return EXIT_FAILURE; @@ -214,7 +220,7 @@ int main(int argc, char** argv) } } - if (fd == NULL) { + if((read || write) && (fd == NULL)) { fprintf(stderr, "Failed to open file: %s\n", path); return EXIT_FAILURE; } @@ -233,8 +239,7 @@ int main(int argc, char** argv) return EXIT_FAILURE; } - if (read) - { + if(read) { ssize_t bytes_written; tmp_length = length; while (tmp_length) @@ -261,7 +266,9 @@ int main(int argc, char** argv) fd = NULL; return EXIT_FAILURE; } - } else { + } + + if(write) { ssize_t bytes_read = fread(data, 1, length, fd); if (bytes_read != length) { fprintf(stderr, "Failed read file (read %d bytes).\n", @@ -297,13 +304,24 @@ int main(int argc, char** argv) } } - result = hackrf_close(device); - if (result != HACKRF_SUCCESS) { - fprintf(stderr, "hackrf_close() failed: %s (%d)\n", - hackrf_error_name(result), result); - fclose(fd); - fd = NULL; - return EXIT_FAILURE; + if(reset) { + result = hackrf_reset(device); + if (result != HACKRF_SUCCESS) { + fprintf(stderr, "hackrf_reset() failed: %s (%d)\n", + hackrf_error_name(result), result); + fclose(fd); + fd = NULL; + return EXIT_FAILURE; + } + } else { + result = hackrf_close(device); + if (result != HACKRF_SUCCESS) { + fprintf(stderr, "hackrf_close() failed: %s (%d)\n", + hackrf_error_name(result), result); + fclose(fd); + fd = NULL; + return EXIT_FAILURE; + } } hackrf_exit(); diff --git a/host/libhackrf/src/hackrf.c b/host/libhackrf/src/hackrf.c index 1ff55195..30c604f2 100644 --- a/host/libhackrf/src/hackrf.c +++ b/host/libhackrf/src/hackrf.c @@ -77,6 +77,7 @@ typedef enum { HACKRF_VENDOR_REQUEST_OPERACAKE_GET_BOARDS = 27, HACKRF_VENDOR_REQUEST_OPERACAKE_SET_PORTS = 28, HACKRF_VENDOR_REQUEST_SET_HW_SYNC_MODE = 29, + HACKRF_VENDOR_REQUEST_RESET = 30, } hackrf_vendor_request; typedef enum { @@ -1829,6 +1830,25 @@ int ADDCALL hackrf_set_operacake_ports(hackrf_device* device, } } +int ADDCALL hackrf_reset(hackrf_device* device) { + int result = libusb_control_transfer( + device->usb_device, + LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, + HACKRF_VENDOR_REQUEST_RESET, + 0, + 0, + NULL, + 0, + 0 + ); + + if( result != 0 ) { + return HACKRF_ERROR_LIBUSB; + } else { + return HACKRF_SUCCESS; + } +} + #ifdef __cplusplus } // __cplusplus defined. #endif diff --git a/host/libhackrf/src/hackrf.h b/host/libhackrf/src/hackrf.h index 3db40f5c..06826aad 100644 --- a/host/libhackrf/src/hackrf.h +++ b/host/libhackrf/src/hackrf.h @@ -222,6 +222,8 @@ extern ADDAPI int ADDCALL hackrf_set_operacake_ports(hackrf_device* device, uint8_t port_a, uint8_t port_b); +extern ADDAPI int ADDCALL hackrf_reset(hackrf_device* device); + #ifdef __cplusplus } // __cplusplus defined. #endif From 9e78ccb4e7505a6cdc4232a3875b4373bb922537 Mon Sep 17 00:00:00 2001 From: Dominic Spill Date: Fri, 27 Jan 2017 16:06:01 -0700 Subject: [PATCH 2/3] Correct argument parsing logic --- host/hackrf-tools/src/hackrf_spiflash.c | 24 ++++++++++++------------ host/hackrf-tools/src/hackrf_transfer.c | 4 ++++ 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/host/hackrf-tools/src/hackrf_spiflash.c b/host/hackrf-tools/src/hackrf_spiflash.c index bb5c53bb..3304b5b3 100644 --- a/host/hackrf-tools/src/hackrf_spiflash.c +++ b/host/hackrf-tools/src/hackrf_spiflash.c @@ -148,8 +148,12 @@ int main(int argc, char** argv) reset = true; break; + case '?': + usage(); + return EXIT_FAILURE; + default: - fprintf(stderr, "opt error: %d\n", opt); + fprintf(stderr, "unknown argument '-%c %s'\n", opt, optarg); usage(); return EXIT_FAILURE; } @@ -162,28 +166,24 @@ int main(int argc, char** argv) } } - if((write == read) && (write == reset)) { - if(write && read) { - fprintf(stderr, "Read and write options are mutually exclusive.\n"); - } else { - fprintf(stderr, "Specify either read, write, or reset option.\n"); - } + if(write && read) { + fprintf(stderr, "Read and write options are mutually exclusive.\n"); usage(); return EXIT_FAILURE; } - - if((read || write) && (path == NULL)) { - fprintf(stderr, "Specify a path to a file.\n"); + + if(!(write || read || reset)) { + fprintf(stderr, "Specify either read, write, or reset option.\n"); usage(); return EXIT_FAILURE; - } + } if( write ) { fd = fopen(path, "rb"); if(fd == NULL) { - printf("Error to open file %s\n", path); + printf("Error opening file %s\n", path); return EXIT_FAILURE; } /* Get size of the file */ diff --git a/host/hackrf-tools/src/hackrf_transfer.c b/host/hackrf-tools/src/hackrf_transfer.c index 8ee5142a..a36166c6 100644 --- a/host/hackrf-tools/src/hackrf_transfer.c +++ b/host/hackrf-tools/src/hackrf_transfer.c @@ -673,6 +673,10 @@ int main(int argc, char** argv) { result = parse_u32(optarg, &crystal_correct_ppm); break; + case '?': + usage(); + return EXIT_FAILURE; + default: fprintf(stderr, "unknown argument '-%c %s'\n", opt, optarg); usage(); From da743b84ef98567c401faafba00740bb2d6af4ce Mon Sep 17 00:00:00 2001 From: Dominic Spill Date: Fri, 27 Jan 2017 16:08:57 -0700 Subject: [PATCH 3/3] Safely call hackrf_close() after resetting the HackRF --- host/hackrf-tools/src/hackrf_spiflash.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/host/hackrf-tools/src/hackrf_spiflash.c b/host/hackrf-tools/src/hackrf_spiflash.c index 3304b5b3..49cc2bf9 100644 --- a/host/hackrf-tools/src/hackrf_spiflash.c +++ b/host/hackrf-tools/src/hackrf_spiflash.c @@ -313,15 +313,15 @@ int main(int argc, char** argv) fd = NULL; return EXIT_FAILURE; } - } else { - result = hackrf_close(device); - if (result != HACKRF_SUCCESS) { - fprintf(stderr, "hackrf_close() failed: %s (%d)\n", - hackrf_error_name(result), result); - fclose(fd); - fd = NULL; - return EXIT_FAILURE; - } + } + + result = hackrf_close(device); + if (result != HACKRF_SUCCESS) { + fprintf(stderr, "hackrf_close() failed: %s (%d)\n", + hackrf_error_name(result), result); + fclose(fd); + fd = NULL; + return EXIT_FAILURE; } hackrf_exit();