From ba148ee047b433bebbc5f073ca33f74299ddd1ee Mon Sep 17 00:00:00 2001 From: Martin Ling Date: Fri, 5 Aug 2022 09:17:32 +0100 Subject: [PATCH] Add a simpler way to check CLKIN status. --- docs/source/external_clock_interface.rst | 2 +- firmware/hackrf_usb/hackrf_usb.c | 1 + firmware/hackrf_usb/usb_api_register.c | 17 ++++++++++++++ firmware/hackrf_usb/usb_api_register.h | 3 +++ host/hackrf-tools/src/hackrf_clock.c | 28 ++++++++++++++++++++---- host/libhackrf/src/hackrf.c | 22 +++++++++++++++++++ host/libhackrf/src/hackrf.h | 2 ++ 7 files changed, 70 insertions(+), 5 deletions(-) diff --git a/docs/source/external_clock_interface.rst b/docs/source/external_clock_interface.rst index 64a6c409..8e01448f 100644 --- a/docs/source/external_clock_interface.rst +++ b/docs/source/external_clock_interface.rst @@ -8,4 +8,4 @@ The CLKIN port on HackRF One is a high impedance input that expects a 0 V to 3 V HackRF One uses CLKIN instead of the internal crystal when a clock signal is detected on CLKIN. The switch to or from CLKIN only happens when a transmit or receive operation begins. -To verify that a signal has been detected on CLKIN, use ``hackrf_debug --si5351c -n 0 -r``. The expected output with a clock detected is `[ 0] -> 0x01`. The expected output with no clock detected is `[ 0] -> 0x51`. +To verify that a signal has been detected on CLKIN, use ``hackrf_clock -i``. The expected output with a clock detected is `CLKIN status: clock signal detected`. The expected output with no clock detected is `CLKIN status: no clock signal detected`. diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index afb779c4..a790c6dc 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -118,6 +118,7 @@ static usb_request_handler_fn vendor_request_handler[] = { usb_vendor_request_get_m0_state, usb_vendor_request_set_tx_underrun_limit, usb_vendor_request_set_rx_overrun_limit, + usb_vendor_request_get_clkin_status, }; static const uint32_t vendor_request_handler_count = diff --git a/firmware/hackrf_usb/usb_api_register.c b/firmware/hackrf_usb/usb_api_register.c index 09aed5d4..728fef72 100644 --- a/firmware/hackrf_usb/usb_api_register.c +++ b/firmware/hackrf_usb/usb_api_register.c @@ -179,3 +179,20 @@ usb_request_status_t usb_vendor_request_set_clkout_enable( } return USB_REQUEST_STATUS_OK; } + +usb_request_status_t usb_vendor_request_get_clkin_status( + usb_endpoint_t* const endpoint, + const usb_transfer_stage_t stage) +{ + if (stage == USB_TRANSFER_STAGE_SETUP) { + endpoint->buffer[0] = si5351c_clkin_signal_valid(&clock_gen); + usb_transfer_schedule_block( + endpoint->in, + &endpoint->buffer, + 1, + NULL, + NULL); + usb_transfer_schedule_ack(endpoint->out); + } + return USB_REQUEST_STATUS_OK; +} diff --git a/firmware/hackrf_usb/usb_api_register.h b/firmware/hackrf_usb/usb_api_register.h index 25f51aca..61b1f54e 100644 --- a/firmware/hackrf_usb/usb_api_register.h +++ b/firmware/hackrf_usb/usb_api_register.h @@ -47,5 +47,8 @@ usb_request_status_t usb_vendor_request_read_rffc5071( usb_request_status_t usb_vendor_request_set_clkout_enable( usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); +usb_request_status_t usb_vendor_request_get_clkin_status( + usb_endpoint_t* const endpoint, + const usb_transfer_stage_t stage); #endif /* end of include guard: __USB_API_REGISTER_H__ */ diff --git a/host/hackrf-tools/src/hackrf_clock.c b/host/hackrf-tools/src/hackrf_clock.c index c41ef767..bf996890 100644 --- a/host/hackrf-tools/src/hackrf_clock.c +++ b/host/hackrf-tools/src/hackrf_clock.c @@ -249,6 +249,7 @@ static void usage() printf("\t-h, --help: this help\n"); printf("\t-r, --read : read settings for clock_num\n"); printf("\t-a, --all: read settings for all clocks\n"); + printf("\t-i, --clkin: get CLKIN status\n"); printf("\t-o, --clkout : enable/disable CLKOUT\n"); printf("\t-d, --device : Serial number of desired HackRF.\n"); printf("\nExamples:\n"); @@ -259,6 +260,7 @@ static struct option long_options[] = { {"help", no_argument, 0, 'h'}, {"read", required_argument, 0, 'r'}, {"all", no_argument, 0, 'a'}, + {"clkin", required_argument, 0, 'i'}, {"clkout", required_argument, 0, 'o'}, {"device", required_argument, 0, 'd'}, {0, 0, 0, 0}, @@ -271,7 +273,9 @@ int main(int argc, char** argv) bool read = false; uint8_t clock = CLOCK_UNDEFINED; bool clkout = false; + bool clkin = false; uint8_t clkout_enable; + uint8_t clkin_status; const char* serial_number = NULL; int result = hackrf_init(); @@ -282,7 +286,7 @@ int main(int argc, char** argv) return EXIT_FAILURE; } - while ((opt = getopt_long(argc, argv, "r:ao:d:h?", long_options, &option_index)) != + while ((opt = getopt_long(argc, argv, "r:aio:d:h?", long_options, &option_index)) != EOF) { switch (opt) { case 'r': @@ -294,6 +298,10 @@ int main(int argc, char** argv) read = true; break; + case 'i': + clkin = true; + break; + case 'o': clkout = true; result = parse_int(optarg, &clkout_enable); @@ -322,9 +330,8 @@ int main(int argc, char** argv) } } - if (!clkout && !read) { - fprintf(stderr, - "Either read or enable CLKOUT option must be specified.\n"); + if (!clkin && !clkout && !read) { + fprintf(stderr, "An operation must be specified.\n"); usage(); return EXIT_FAILURE; } @@ -347,6 +354,19 @@ int main(int argc, char** argv) } } + if (clkin) { + result = hackrf_get_clkin_status(device, &clkin_status); + if (result) { + printf("hackrf_get_clkin_status() failed: %s (%d)\n", + hackrf_error_name(result), + result); + return EXIT_FAILURE; + } + printf("CLKIN status: %s\n", + clkin_status ? "clock signal detected" : + "no clock signal detected"); + } + if (read) { if (clock == CLOCK_UNDEFINED) { si5351c_read_configuration(device); diff --git a/host/libhackrf/src/hackrf.c b/host/libhackrf/src/hackrf.c index 7e3453cd..c9e7e5d0 100644 --- a/host/libhackrf/src/hackrf.c +++ b/host/libhackrf/src/hackrf.c @@ -99,6 +99,7 @@ typedef enum { HACKRF_VENDOR_REQUEST_GET_M0_STATE = 41, HACKRF_VENDOR_REQUEST_SET_TX_UNDERRUN_LIMIT = 42, HACKRF_VENDOR_REQUEST_SET_RX_OVERRUN_LIMIT = 43, + HACKRF_VENDOR_REQUEST_GET_CLKIN_STATUS = 44, } hackrf_vendor_request; #define USB_CONFIG_STANDARD 0x1 @@ -2521,6 +2522,27 @@ int ADDCALL hackrf_set_clkout_enable(hackrf_device* device, const uint8_t value) } } +int ADDCALL hackrf_get_clkin_status(hackrf_device* device, uint8_t* status) +{ + USB_API_REQUIRED(device, 0x0106) + int result; + result = libusb_control_transfer( + device->usb_device, + LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, + HACKRF_VENDOR_REQUEST_GET_CLKIN_STATUS, + 0, + 0, + status, + 1, + 0); + if (result < 1) { + last_libusb_error = result; + return HACKRF_ERROR_LIBUSB; + } else { + return HACKRF_SUCCESS; + } +} + int ADDCALL hackrf_operacake_gpio_test( hackrf_device* device, const uint8_t address, diff --git a/host/libhackrf/src/hackrf.h b/host/libhackrf/src/hackrf.h index 60fb5729..0d3efc8f 100644 --- a/host/libhackrf/src/hackrf.h +++ b/host/libhackrf/src/hackrf.h @@ -440,6 +440,8 @@ extern ADDAPI int ADDCALL hackrf_set_clkout_enable( hackrf_device* device, const uint8_t value); +extern ADDAPI int ADDCALL hackrf_get_clkin_status(hackrf_device* device, uint8_t* status); + extern ADDAPI int ADDCALL hackrf_operacake_gpio_test( hackrf_device* device, uint8_t address,