Add a simpler way to check CLKIN status.

This commit is contained in:
Martin Ling
2022-08-05 09:17:32 +01:00
parent 01e0702013
commit ba148ee047
7 changed files with 70 additions and 5 deletions

View File

@ -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`.

View File

@ -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 =

View File

@ -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;
}

View File

@ -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__ */

View File

@ -249,6 +249,7 @@ static void usage()
printf("\t-h, --help: this help\n");
printf("\t-r, --read <clock_num>: 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 <clkout_enable>: enable/disable CLKOUT\n");
printf("\t-d, --device <serial_number>: 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);

View File

@ -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,

View File

@ -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,