diff --git a/firmware/common/hackrf_core.h b/firmware/common/hackrf_core.h index f44464a7..bff1513c 100644 --- a/firmware/common/hackrf_core.h +++ b/firmware/common/hackrf_core.h @@ -42,23 +42,6 @@ extern "C" { #include "rf_path.h" #include "cpld_jtag.h" -/* hardware identification number */ -#define BOARD_ID_JAWBREAKER 1 -#define BOARD_ID_HACKRF_ONE 2 -#define BOARD_ID_RAD1O 3 - -#ifdef JAWBREAKER - #define BOARD_ID BOARD_ID_JAWBREAKER -#endif - -#ifdef HACKRF_ONE - #define BOARD_ID BOARD_ID_HACKRF_ONE -#endif - -#ifdef RAD1O - #define BOARD_ID BOARD_ID_RAD1O -#endif - /* * SCU PinMux */ diff --git a/firmware/common/platform_detect.c b/firmware/common/platform_detect.c new file mode 100644 index 00000000..05c297b3 --- /dev/null +++ b/firmware/common/platform_detect.c @@ -0,0 +1,231 @@ +/* + * Copyright 2022 Great Scott Gadgets + * + * 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 "platform_detect.h" +#include "gpio_lpc.h" +#include "hackrf_core.h" + +#include +#include + +static board_id_t platform = BOARD_ID_UNDETECTED; +static board_rev_t revision = BOARD_REV_UNDETECTED; + +static struct gpio_t gpio2_9_on_P5_0 = GPIO(2, 9); +static struct gpio_t gpio3_6_on_P6_10 = GPIO(3, 6); + +#define P5_0_PUP (1 << 0) +#define P5_0_PDN (1 << 1) +#define P6_10_PUP (1 << 2) +#define P6_10_PDN (1 << 3) + +/* + * Jawbreaker has a pull-down on P6_10 and nothing on P5_0. + * rad1o has a pull-down on P6_10 and a pull-down on P5_0. + * HackRF One OG has a pull-down on P6_10 and a pull-up on P5_0. + * HackRF One r9 has a pull-up on P6_10 and a pull-down on P5_0. + */ + +#define JAWBREAKER_RESISTORS (P6_10_PDN) +#define RAD1O_RESISTORS (P6_10_PDN | P5_0_PDN) +#define HACKRF1_OG_RESISTORS (P6_10_PDN | P5_0_PUP) +#define HACKRF1_R9_RESISTORS (P6_10_PUP | P5_0_PDN) + +/* + * LEDs are configured so that they flash if the detected hardware platform is + * not supported by the firmware binary. Only two LEDs are flashed for a + * hardware detection failure, but three LEDs are flashed if CPLD configuration + * fails. + */ +static struct gpio_t gpio_led1 = GPIO(2, 1); +static struct gpio_t gpio_led2 = GPIO(2, 2); +static struct gpio_t gpio_led3 = GPIO(2, 8); + +uint8_t adc_read(uint8_t pin) +{ + pin &= 0x7; + uint8_t pin_mask = (1 << pin); + ADC0_CR = ADC_CR_SEL(pin_mask) | ADC_CR_CLKDIV(45) | ADC_CR_CLKS(2) | ADC_CR_PDN | + ADC_CR_START(1); + while (!(ADC0_GDR & ADC_DR_DONE) || (((ADC0_GDR >> 24) & 0x7) != pin)) {} + return (ADC0_GDR >> 6) & 0x03FF; +} + +void adc_off(void) +{ + ADC0_CR = 0; +} + +/* + * Starting with r6, HackRF One has pin straps on ADC pins that indicate + * hardware revision. Those pins were unconnected prior to r6, so we test for + * the unconnected state by averaging several ADC readings. + */ +#define NUM_SAMPLES (10) +#define LOW_THRESHOLD (2 * NUM_SAMPLES) +#define HIGH_THRESHOLD (253 * NUM_SAMPLES) + +typedef enum { + PIN_STRAP_HIGH, + PIN_STRAP_LOW, + PIN_STRAP_ABSENT, +} pin_strap_t; + +pin_strap_t check_pin_strap(uint8_t pin) +{ + int i; + uint32_t sum = 0; + + for (i = 0; i < NUM_SAMPLES; i++) { + sum += adc_read(pin); + } + adc_off(); + if (sum > HIGH_THRESHOLD) { + return PIN_STRAP_HIGH; + } else if (sum < LOW_THRESHOLD) { + return PIN_STRAP_LOW; + } else { + return PIN_STRAP_ABSENT; + } +} + +void detect_hardware_platform(void) +{ + uint8_t detected_resistors = 0; + + scu_pinmux(SCU_PINMUX_LED2, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION0); + scu_pinmux(SCU_PINMUX_LED3, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION0); + gpio_input(&gpio_led1); + gpio_output(&gpio_led2); + gpio_output(&gpio_led3); + + gpio_input(&gpio2_9_on_P5_0); + gpio_input(&gpio3_6_on_P6_10); + + scu_pinmux(P5_0, SCU_GPIO_PUP | SCU_CONF_FUNCTION0); + scu_pinmux(P6_10, SCU_GPIO_PUP | SCU_CONF_FUNCTION0); + delay(20); + + scu_pinmux(P5_0, SCU_GPIO_PDN | SCU_CONF_FUNCTION0); + scu_pinmux(P6_10, SCU_GPIO_PDN | SCU_CONF_FUNCTION0); + delay(20); + detected_resistors |= (gpio_read(&gpio2_9_on_P5_0)) ? P5_0_PUP : 0; + detected_resistors |= (gpio_read(&gpio3_6_on_P6_10)) ? P6_10_PUP : 0; + + scu_pinmux(P5_0, SCU_GPIO_PUP | SCU_CONF_FUNCTION0); + scu_pinmux(P6_10, SCU_GPIO_PUP | SCU_CONF_FUNCTION0); + delay(20); + detected_resistors |= (gpio_read(&gpio2_9_on_P5_0)) ? 0 : P5_0_PDN; + detected_resistors |= (gpio_read(&gpio3_6_on_P6_10)) ? 0 : P6_10_PDN; + + scu_pinmux(P5_0, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION0); + scu_pinmux(P6_10, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION0); + + switch (detected_resistors) { + case JAWBREAKER_RESISTORS: + if (!(supported_platform() & PLATFORM_JAWBREAKER)) { + halt_and_flash(3000000); + } + platform = BOARD_ID_JAWBREAKER; + return; + case RAD1O_RESISTORS: + if (!(supported_platform() & PLATFORM_RAD1O)) { + halt_and_flash(3000000); + } + platform = BOARD_ID_RAD1O; + return; + case HACKRF1_OG_RESISTORS: + if (!(supported_platform() & PLATFORM_HACKRF1_OG)) { + halt_and_flash(3000000); + } + platform = BOARD_ID_HACKRF1_OG; + break; + case HACKRF1_R9_RESISTORS: + if (!(supported_platform() & PLATFORM_HACKRF1_R9)) { + halt_and_flash(3000000); + } + platform = BOARD_ID_HACKRF1_R9; + break; + default: + platform = BOARD_ID_UNRECOGNIZED; + halt_and_flash(1000000); + } + + pin_strap_t adc0_3 = check_pin_strap(3); + pin_strap_t adc0_4 = check_pin_strap(4); + pin_strap_t adc0_7 = check_pin_strap(7); + + if ((adc0_3 == PIN_STRAP_ABSENT) && (adc0_4 == PIN_STRAP_ABSENT) && + (adc0_7 == PIN_STRAP_ABSENT) && (platform == BOARD_ID_HACKRF1_OG)) { + revision = BOARD_REV_HACKRF1_OLD; + } else if ( + (adc0_3 == PIN_STRAP_HIGH) && (adc0_4 == PIN_STRAP_HIGH) && + (platform == BOARD_ID_HACKRF1_OG)) { + revision = BOARD_REV_HACKRF1_R6; + } else if ( + (adc0_3 == PIN_STRAP_LOW) && (adc0_4 == PIN_STRAP_HIGH) && + (platform == BOARD_ID_HACKRF1_OG)) { + revision = BOARD_REV_HACKRF1_R7; + } else if ( + (adc0_3 == PIN_STRAP_HIGH) && (adc0_4 == PIN_STRAP_LOW) && + (platform == BOARD_ID_HACKRF1_OG)) { + revision = BOARD_REV_HACKRF1_R8; + } else if ( + (adc0_3 == PIN_STRAP_LOW) && (adc0_4 == PIN_STRAP_LOW) && + (platform == BOARD_ID_HACKRF1_R9)) { + revision = BOARD_REV_HACKRF1_R9; + } else { + revision = BOARD_REV_UNRECOGNIZED; + } + + if ((revision > BOARD_REV_HACKRF1_OLD) && (adc0_7 == PIN_STRAP_LOW)) { + revision |= BOARD_REV_GSG; + } +} + +board_id_t detected_platform(void) +{ + return platform; +} + +board_rev_t detected_revision(void) +{ + return revision; +} + +uint32_t supported_platform(void) +{ + uint32_t binary_platform = 0; + +#ifdef JAWBREAKER + binary_platform = PLATFORM_JAWBREAKER; +#endif + +#ifdef HACKRF_ONE + binary_platform = PLATFORM_HACKRF1_OG; +#endif + +#ifdef RAD1O + binary_platform = PLATFORM_RAD1O; +#endif + + return binary_platform; +} diff --git a/firmware/common/platform_detect.h b/firmware/common/platform_detect.h new file mode 100644 index 00000000..fbd4fcea --- /dev/null +++ b/firmware/common/platform_detect.h @@ -0,0 +1,64 @@ +/* + * Copyright 2022 Great Scott Gadgets + * + * This file is part of HackRF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __PLATFORM_DETECT_H__ +#define __PLATFORM_DETECT_H__ + +#include + +#define BOARD_REV_GSG (0x80) + +#define PLATFORM_JAWBREAKER (1 << 0) +#define PLATFORM_HACKRF1_OG (1 << 1) +#define PLATFORM_RAD1O (1 << 2) +#define PLATFORM_HACKRF1_R9 (1 << 3) + +typedef enum { + BOARD_ID_JELLYBEAN = 0, + BOARD_ID_JAWBREAKER = 1, + BOARD_ID_HACKRF1_OG = 2, /* HackRF One prior to r9 */ + BOARD_ID_RAD1O = 3, + BOARD_ID_HACKRF1_R9 = 4, + BOARD_ID_UNRECOGNIZED = 0xFE, /* tried detection but did not recognize board */ + BOARD_ID_UNDETECTED = 0xFF, /* detection not yet attempted */ +} board_id_t; + +typedef enum { + BOARD_REV_HACKRF1_OLD = 0, + BOARD_REV_HACKRF1_R6 = 1, + BOARD_REV_HACKRF1_R7 = 2, + BOARD_REV_HACKRF1_R8 = 3, + BOARD_REV_HACKRF1_R9 = 4, + BOARD_REV_GSG_HACKRF1_R6 = 0x81, + BOARD_REV_GSG_HACKRF1_R7 = 0x82, + BOARD_REV_GSG_HACKRF1_R8 = 0x83, + BOARD_REV_GSG_HACKRF1_R9 = 0x84, + BOARD_REV_UNRECOGNIZED = + 0xFE, /* tried detection but did not recognize revision */ + BOARD_REV_UNDETECTED = 0xFF, /* detection not yet attempted */ +} board_rev_t; + +void detect_hardware_platform(void); +board_id_t detected_platform(void); +board_rev_t detected_revision(void); +uint32_t supported_platform(void); + +#endif //__PLATFORM_DETECT_H__ diff --git a/firmware/hackrf-common.cmake b/firmware/hackrf-common.cmake index 4e7b3c9e..7d6b2c7a 100644 --- a/firmware/hackrf-common.cmake +++ b/firmware/hackrf-common.cmake @@ -184,6 +184,7 @@ macro(DeclareTargets) ${PATH_HACKRF_FIRMWARE_COMMON}/spi_ssp.c ${PATH_HACKRF_FIRMWARE_COMMON}/gpio_lpc.c ${PATH_HACKRF_FIRMWARE_COMMON}/hackrf_ui.c + ${PATH_HACKRF_FIRMWARE_COMMON}/platform_detect.c ) if(BOARD STREQUAL "RAD1O") diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index a790c6dc..39ff2081 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -52,8 +52,8 @@ #include "usb_api_m0_state.h" #include "cpld_xc2c.h" #include "portapack.h" - #include "hackrf_ui.h" +#include "platform_detect.h" extern uint32_t __m0_start__; extern uint32_t __m0_end__; @@ -119,6 +119,8 @@ static usb_request_handler_fn vendor_request_handler[] = { usb_vendor_request_set_tx_underrun_limit, usb_vendor_request_set_rx_overrun_limit, usb_vendor_request_get_clkin_status, + usb_vendor_request_read_board_rev, + usb_vendor_request_read_supported_platform, }; static const uint32_t vendor_request_handler_count = @@ -224,6 +226,7 @@ int main(void) // Copy M0 image from ROM before SPIFI is disabled m0_rom_to_ram(); + detect_hardware_platform(); pin_setup(); enable_1v8_power(); #if (defined HACKRF_ONE || defined RAD1O) diff --git a/firmware/hackrf_usb/usb_api_board_info.c b/firmware/hackrf_usb/usb_api_board_info.c index e8c4f5ad..041fd370 100644 --- a/firmware/hackrf_usb/usb_api_board_info.c +++ b/firmware/hackrf_usb/usb_api_board_info.c @@ -21,6 +21,7 @@ */ #include "usb_api_board_info.h" +#include "platform_detect.h" #include #include @@ -37,7 +38,7 @@ usb_request_status_t usb_vendor_request_read_board_id( const usb_transfer_stage_t stage) { if (stage == USB_TRANSFER_STAGE_SETUP) { - endpoint->buffer[0] = BOARD_ID; + endpoint->buffer[0] = detected_platform(); usb_transfer_schedule_block( endpoint->in, &endpoint->buffer, @@ -122,3 +123,41 @@ usb_request_status_t usb_vendor_request_reset( } return USB_REQUEST_STATUS_OK; } + +usb_request_status_t usb_vendor_request_read_board_rev( + usb_endpoint_t* const endpoint, + const usb_transfer_stage_t stage) +{ + if (stage == USB_TRANSFER_STAGE_SETUP) { + endpoint->buffer[0] = detected_revision(); + usb_transfer_schedule_block( + endpoint->in, + &endpoint->buffer, + 1, + NULL, + NULL); + usb_transfer_schedule_ack(endpoint->out); + } + return USB_REQUEST_STATUS_OK; +} + +usb_request_status_t usb_vendor_request_read_supported_platform( + usb_endpoint_t* const endpoint, + const usb_transfer_stage_t stage) +{ + if (stage == USB_TRANSFER_STAGE_SETUP) { + uint32_t platform = supported_platform(); + endpoint->buffer[0] = (platform >> 24) & 0xff; + endpoint->buffer[1] = (platform >> 16) & 0xff; + endpoint->buffer[2] = (platform >> 8) & 0xff; + endpoint->buffer[3] = platform & 0xff; + usb_transfer_schedule_block( + endpoint->in, + &endpoint->buffer, + 4, + NULL, + NULL); + usb_transfer_schedule_ack(endpoint->out); + } + return USB_REQUEST_STATUS_OK; +} diff --git a/firmware/hackrf_usb/usb_api_board_info.h b/firmware/hackrf_usb/usb_api_board_info.h index 03dd62a6..ce52e599 100644 --- a/firmware/hackrf_usb/usb_api_board_info.h +++ b/firmware/hackrf_usb/usb_api_board_info.h @@ -45,5 +45,11 @@ usb_request_status_t usb_vendor_request_read_partid_serialno( usb_request_status_t usb_vendor_request_reset( usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); +usb_request_status_t usb_vendor_request_read_board_rev( + usb_endpoint_t* const endpoint, + const usb_transfer_stage_t stage); +usb_request_status_t usb_vendor_request_read_supported_platform( + 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 6a301c81..6cc98dcd 160000 --- a/firmware/libopencm3 +++ b/firmware/libopencm3 @@ -1 +1 @@ -Subproject commit 6a301c81f4144d72fc881eb4fc7cc77aa1a32a67 +Subproject commit 6cc98dcd36653cd528c55a593c4989b8530b6b50 diff --git a/host/hackrf-tools/src/hackrf_info.c b/host/hackrf-tools/src/hackrf_info.c index a682a529..278e8885 100644 --- a/host/hackrf-tools/src/hackrf_info.c +++ b/host/hackrf-tools/src/hackrf_info.c @@ -26,10 +26,68 @@ #include #include +void print_board_rev(uint8_t board_rev) +{ + switch (board_rev) { + case BOARD_REV_UNDETECTED: + printf("Error: Hardware revision not yet detected by firmware.\n"); + return; + case BOARD_REV_UNRECOGNIZED: + printf("Warning: Hardware revision not recognized by firmware.\n"); + return; + } + printf("Hardware Revision: %s\n", hackrf_board_rev_name(board_rev)); + if (board_rev > BOARD_REV_HACKRF1_OLD) { + if (board_rev & HACKRF_BOARD_REV_GSG) { + printf("Hardware appears to have been manufactured by Great Scott Gadgets.\n"); + } else { + printf("Hardware does not appear to have been manufactured by Great Scott Gadgets.\n"); + } + } +} + +void print_supported_platform(uint32_t platform, uint8_t board_id) +{ + printf("Hardware supported by installed firmware:\n"); + if (platform & HACKRF_PLATFORM_JAWBREAKER) { + printf(" Jawbreaker\n"); + } + if (platform & HACKRF_PLATFORM_RAD1O) { + printf(" rad1o\n"); + } + if ((platform & HACKRF_PLATFORM_HACKRF1_OG) || + (platform & HACKRF_PLATFORM_HACKRF1_R9)) { + printf(" HackRF One\n"); + } + switch (board_id) { + case BOARD_ID_HACKRF1_OG: + if (!(platform & HACKRF_PLATFORM_HACKRF1_OG)) { + printf("Error: Firmware does not support HackRF One revisions older than r9.\n"); + } + break; + case BOARD_ID_HACKRF1_R9: + if (!(platform & HACKRF_PLATFORM_HACKRF1_R9)) { + printf("Error: Firmware does not support HackRF One r9.\n"); + } + break; + case BOARD_ID_JAWBREAKER: + if (platform & HACKRF_PLATFORM_JAWBREAKER) { + break; + } + case BOARD_ID_RAD1O: + if (platform & HACKRF_PLATFORM_RAD1O) { + break; + } + printf("Error: Firmware does not support hardware platform.\n"); + } +} + int main(void) { int result = HACKRF_SUCCESS; - uint8_t board_id = BOARD_ID_INVALID; + uint8_t board_id = BOARD_ID_UNDETECTED; + uint8_t board_rev = BOARD_REV_UNDETECTED; + uint32_t supported_platform = 0; char version[255 + 1]; uint16_t usb_version; read_partid_serialno_t read_partid_serialno; @@ -130,6 +188,31 @@ int main(void) read_partid_serialno.part_id[0], read_partid_serialno.part_id[1]); + if ((usb_version >= 0x0106) && ((board_id == 2) || (board_id == 4))) { + result = hackrf_board_rev_read(device, &board_rev); + if (result != HACKRF_SUCCESS) { + fprintf(stderr, + "hackrf_board_rev_read() failed: %s (%d)\n", + hackrf_error_name(result), + result); + return EXIT_FAILURE; + } + print_board_rev(board_rev); + } + if (usb_version >= 0x0106) { + result = hackrf_supported_platform_read( + device, + &supported_platform); + if (result != HACKRF_SUCCESS) { + fprintf(stderr, + "hackrf_supported_platform_read() failed: %s (%d)\n", + hackrf_error_name(result), + result); + return EXIT_FAILURE; + } + print_supported_platform(supported_platform, board_id); + } + result = hackrf_get_operacake_boards(device, &operacakes[0]); if ((result != HACKRF_SUCCESS) && (result != HACKRF_ERROR_USB_API_VERSION)) { diff --git a/host/hackrf-tools/src/hackrf_spiflash.c b/host/hackrf-tools/src/hackrf_spiflash.c index 6020491b..7a20edeb 100644 --- a/host/hackrf-tools/src/hackrf_spiflash.c +++ b/host/hackrf-tools/src/hackrf_spiflash.c @@ -78,7 +78,7 @@ int compatibility_check(uint8_t* data, int length, hackrf_device* device) dev_str = "HackRF Jawbreaker"; str_len = 17; break; - case BOARD_ID_HACKRF_ONE: + case BOARD_ID_HACKRF1_OG: dev_str = "HackRF One"; str_len = 10; break; @@ -87,7 +87,7 @@ int compatibility_check(uint8_t* data, int length, hackrf_device* device) str_len = 5; break; default: - printf("Unknown Board ID"); + printf("Unsupported Board ID"); return 1; } // Search for dev_str in uint8_t array of bytes that we're flashing diff --git a/host/libhackrf/src/hackrf.c b/host/libhackrf/src/hackrf.c index eaf3a935..65554e1f 100644 --- a/host/libhackrf/src/hackrf.c +++ b/host/libhackrf/src/hackrf.c @@ -100,6 +100,8 @@ typedef enum { 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_BOARD_REV_READ = 45, + HACKRF_VENDOR_REQUEST_SUPPORTED_PLATFORM_READ = 46, } hackrf_vendor_request; #define USB_CONFIG_STANDARD 0x1 @@ -2140,17 +2142,23 @@ const char* ADDCALL hackrf_board_id_name(enum hackrf_board_id board_id) case BOARD_ID_JAWBREAKER: return "Jawbreaker"; - case BOARD_ID_HACKRF_ONE: + case BOARD_ID_HACKRF1_OG: return "HackRF One"; case BOARD_ID_RAD1O: return "rad1o"; - case BOARD_ID_INVALID: - return "Invalid Board ID"; + case BOARD_ID_HACKRF1_R9: + return "HackRF One"; + + case BOARD_ID_UNRECOGNIZED: + return "unrecognized"; + + case BOARD_ID_UNDETECTED: + return "undetected"; default: - return "Unknown Board ID"; + return "unknown"; } } @@ -2783,6 +2791,85 @@ uint32_t ADDCALL hackrf_get_transfer_queue_depth(hackrf_device* device) return TRANSFER_COUNT; } +int ADDCALL hackrf_board_rev_read(hackrf_device* device, uint8_t* value) +{ + 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_BOARD_REV_READ, + 0, + 0, + value, + 1, + 0); + + if (result < 1) { + last_libusb_error = result; + return HACKRF_ERROR_LIBUSB; + } else { + return HACKRF_SUCCESS; + } +} + +extern ADDAPI const char* ADDCALL hackrf_board_rev_name(enum hackrf_board_rev board_rev) +{ + switch (board_rev) { + case BOARD_REV_HACKRF1_OLD: + return "older than r6"; + + case BOARD_REV_HACKRF1_R6: + case BOARD_REV_GSG_HACKRF1_R6: + return "r6"; + + case BOARD_REV_HACKRF1_R7: + case BOARD_REV_GSG_HACKRF1_R7: + return "r7"; + + case BOARD_REV_HACKRF1_R8: + case BOARD_REV_GSG_HACKRF1_R8: + return "r8"; + + case BOARD_REV_HACKRF1_R9: + case BOARD_REV_GSG_HACKRF1_R9: + return "r9"; + + case BOARD_ID_UNRECOGNIZED: + return "unrecognized"; + + case BOARD_ID_UNDETECTED: + return "undetected"; + + default: + return "unknown"; + } +} + +int ADDCALL hackrf_supported_platform_read(hackrf_device* device, uint32_t* value) +{ + unsigned char data[4]; + 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_SUPPORTED_PLATFORM_READ, + 0, + 0, + &data[0], + 4, + 0); + + if (result < 1) { + last_libusb_error = result; + return HACKRF_ERROR_LIBUSB; + } else { + *value = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]; + return HACKRF_SUCCESS; + } +} + #ifdef __cplusplus } // __cplusplus defined. #endif diff --git a/host/libhackrf/src/hackrf.h b/host/libhackrf/src/hackrf.h index 87a52ac5..68bfd1cd 100644 --- a/host/libhackrf/src/hackrf.h +++ b/host/libhackrf/src/hackrf.h @@ -74,12 +74,36 @@ enum hackrf_error { HACKRF_ERROR_OTHER = -9999, }; +#define HACKRF_BOARD_REV_GSG (0x80) + +#define HACKRF_PLATFORM_JAWBREAKER (1 << 0) +#define HACKRF_PLATFORM_HACKRF1_OG (1 << 1) +#define HACKRF_PLATFORM_RAD1O (1 << 2) +#define HACKRF_PLATFORM_HACKRF1_R9 (1 << 3) + enum hackrf_board_id { BOARD_ID_JELLYBEAN = 0, BOARD_ID_JAWBREAKER = 1, - BOARD_ID_HACKRF_ONE = 2, + BOARD_ID_HACKRF1_OG = 2, /* HackRF One prior to r9 */ BOARD_ID_RAD1O = 3, - BOARD_ID_INVALID = 0xFF, + BOARD_ID_HACKRF1_R9 = 4, + BOARD_ID_UNRECOGNIZED = 0xFE, /* tried detection but did not recognize board */ + BOARD_ID_UNDETECTED = 0xFF, /* detection not yet attempted */ +}; + +enum hackrf_board_rev { + BOARD_REV_HACKRF1_OLD = 0, + BOARD_REV_HACKRF1_R6 = 1, + BOARD_REV_HACKRF1_R7 = 2, + BOARD_REV_HACKRF1_R8 = 3, + BOARD_REV_HACKRF1_R9 = 4, + BOARD_REV_GSG_HACKRF1_R6 = 0x81, + BOARD_REV_GSG_HACKRF1_R7 = 0x82, + BOARD_REV_GSG_HACKRF1_R8 = 0x83, + BOARD_REV_GSG_HACKRF1_R9 = 0x84, + BOARD_REV_UNRECOGNIZED = + 0xFE, /* tried detection but did not recognize revision */ + BOARD_REV_UNDETECTED = 0xFF, /* detection not yet attempted */ }; enum hackrf_usb_board_id { @@ -466,6 +490,14 @@ extern ADDAPI size_t ADDCALL hackrf_get_transfer_buffer_size(hackrf_device* devi extern ADDAPI uint32_t ADDCALL hackrf_get_transfer_queue_depth(hackrf_device* device); +extern ADDAPI int ADDCALL hackrf_board_rev_read(hackrf_device* device, uint8_t* value); + +extern ADDAPI const char* ADDCALL hackrf_board_rev_name(enum hackrf_board_rev board_rev); + +extern ADDAPI int ADDCALL hackrf_supported_platform_read( + hackrf_device* device, + uint32_t* value); + #ifdef __cplusplus } // __cplusplus defined. #endif