From 93d9f9b45c639b66f885acce6cae976286a8d3f9 Mon Sep 17 00:00:00 2001 From: Michael Ossmann Date: Wed, 21 Feb 2024 23:29:27 -0500 Subject: [PATCH 1/2] Use 10-bit ADC value for pin strap detection Previously we thought we were configuring the ADC for 8-bit values, but we did so incorrectly. We were throwing away the top two bits of a 10-bit value. This never caused a problem because the only fixed voltages we used were at the extreme minimum or maximum of the ADC range. --- firmware/common/platform_detect.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/firmware/common/platform_detect.c b/firmware/common/platform_detect.c index 5430c5d82..263ebf105 100644 --- a/firmware/common/platform_detect.c +++ b/firmware/common/platform_detect.c @@ -60,12 +60,14 @@ 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) +/* + * Return 10-bit ADC result. + */ +uint16_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); + ADC0_CR = ADC_CR_SEL(pin_mask) | ADC_CR_CLKDIV(45) | ADC_CR_PDN | ADC_CR_START(1); while (!(ADC0_GDR & ADC_DR_DONE) || (((ADC0_GDR >> 24) & 0x7) != pin)) {} return (ADC0_GDR >> 6) & 0x03FF; } @@ -82,7 +84,7 @@ void adc_off(void) */ #define NUM_SAMPLES (10) #define LOW_THRESHOLD (2 * NUM_SAMPLES) -#define HIGH_THRESHOLD (253 * NUM_SAMPLES) +#define HIGH_THRESHOLD (1022 * NUM_SAMPLES) typedef enum { PIN_STRAP_HIGH, From 24ac1edf5a0113ea6618531bc8e2d3088a235acc Mon Sep 17 00:00:00 2001 From: Michael Ossmann Date: Wed, 21 Feb 2024 23:48:54 -0500 Subject: [PATCH 2/2] Support detection of HackRF One r10 --- firmware/common/platform_detect.c | 115 +++++++++++++++++++----------- firmware/common/platform_detect.h | 2 + host/libhackrf/src/hackrf.c | 4 ++ host/libhackrf/src/hackrf.h | 8 +++ 4 files changed, 88 insertions(+), 41 deletions(-) diff --git a/firmware/common/platform_detect.c b/firmware/common/platform_detect.c index 263ebf105..85113b083 100644 --- a/firmware/common/platform_detect.c +++ b/firmware/common/platform_detect.c @@ -83,16 +83,14 @@ void adc_off(void) * the unconnected state by averaging several ADC readings. */ #define NUM_SAMPLES (10) -#define LOW_THRESHOLD (2 * NUM_SAMPLES) -#define HIGH_THRESHOLD (1022 * NUM_SAMPLES) +#define LOW_THRESHOLD (2) +#define HIGH_THRESHOLD (1022) -typedef enum { - PIN_STRAP_HIGH, - PIN_STRAP_LOW, - PIN_STRAP_ABSENT, -} pin_strap_t; +#define HIGH(x) ((x) > HIGH_THRESHOLD) +#define LOW(x) ((x) < LOW_THRESHOLD) +#define ABSENT(x) (((x) >= LOW_THRESHOLD) && ((x) <= HIGH_THRESHOLD)) -pin_strap_t check_pin_strap(uint8_t pin) +uint32_t check_pin_strap(uint8_t pin) { int i; uint32_t sum = 0; @@ -101,15 +99,53 @@ pin_strap_t check_pin_strap(uint8_t pin) 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; - } + return (sum / NUM_SAMPLES); } +/* + * Starting with r10, HackRF One uses a voltage divider on ADC0_3 to set an + * analog voltage that indicates the hardware revision. The high five bits of + * the ADC result are mapped to 32 revisions. HackRF One r8 also fits into this + * scheme with ADC0_3 tied to VCC. + */ +// clang-format off +static const uint8_t revision_from_adc[32] = { + BOARD_REV_UNRECOGNIZED, + BOARD_REV_UNRECOGNIZED, + BOARD_REV_UNRECOGNIZED, + BOARD_REV_UNRECOGNIZED, + BOARD_REV_UNRECOGNIZED, + BOARD_REV_UNRECOGNIZED, + BOARD_REV_UNRECOGNIZED, + BOARD_REV_UNRECOGNIZED, + BOARD_REV_UNRECOGNIZED, + BOARD_REV_UNRECOGNIZED, + BOARD_REV_UNRECOGNIZED, + BOARD_REV_UNRECOGNIZED, + BOARD_REV_UNRECOGNIZED, + BOARD_REV_UNRECOGNIZED, + BOARD_REV_UNRECOGNIZED, + BOARD_REV_UNRECOGNIZED, + BOARD_REV_UNRECOGNIZED, + BOARD_REV_UNRECOGNIZED, + BOARD_REV_UNRECOGNIZED, + BOARD_REV_UNRECOGNIZED, + BOARD_REV_UNRECOGNIZED, + BOARD_REV_UNRECOGNIZED, + BOARD_REV_UNRECOGNIZED, + BOARD_REV_UNRECOGNIZED, + BOARD_REV_UNRECOGNIZED, + BOARD_REV_UNRECOGNIZED, + BOARD_REV_UNRECOGNIZED, + BOARD_REV_UNRECOGNIZED, + BOARD_REV_UNRECOGNIZED, + BOARD_REV_UNRECOGNIZED, + BOARD_REV_HACKRF1_R10, + BOARD_REV_HACKRF1_R8 +}; + +// clang-format on + void detect_hardware_platform(void) { uint8_t detected_resistors = 0; @@ -177,34 +213,31 @@ void detect_hardware_platform(void) 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; + uint32_t adc0_3 = check_pin_strap(3); + uint32_t adc0_4 = check_pin_strap(4); + uint32_t adc0_7 = check_pin_strap(7); + + if (platform == BOARD_ID_HACKRF1_OG) { + if (ABSENT(adc0_3) && ABSENT(adc0_4) && ABSENT(adc0_7)) { + revision = BOARD_REV_HACKRF1_OLD; + } else if (HIGH(adc0_3) && HIGH(adc0_4)) { + revision = BOARD_REV_HACKRF1_R6; + } else if (LOW(adc0_3) && HIGH(adc0_4)) { + revision = BOARD_REV_HACKRF1_R7; + } else if (LOW(adc0_4)) { + revision = revision_from_adc[adc0_3 >> 5]; + } else { + revision = BOARD_REV_UNRECOGNIZED; + } + } else if (platform == BOARD_ID_HACKRF1_R9) { + if (LOW(adc0_3) && LOW(adc0_4)) { + revision = BOARD_REV_HACKRF1_R9; + } else { + revision = BOARD_REV_UNRECOGNIZED; + } } - if ((revision > BOARD_REV_HACKRF1_OLD) && (adc0_7 == PIN_STRAP_LOW)) { + if ((revision > BOARD_REV_HACKRF1_OLD) && LOW(adc0_7)) { revision |= BOARD_REV_GSG; } } diff --git a/firmware/common/platform_detect.h b/firmware/common/platform_detect.h index a24a158f8..49a2c4ff0 100644 --- a/firmware/common/platform_detect.h +++ b/firmware/common/platform_detect.h @@ -47,10 +47,12 @@ typedef enum { BOARD_REV_HACKRF1_R7 = 2, BOARD_REV_HACKRF1_R8 = 3, BOARD_REV_HACKRF1_R9 = 4, + BOARD_REV_HACKRF1_R10 = 5, 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_GSG_HACKRF1_R10 = 0x85, BOARD_REV_UNRECOGNIZED = 0xFE, /* tried detection but did not recognize revision */ BOARD_REV_UNDETECTED = 0xFF, /* detection not yet attempted */ diff --git a/host/libhackrf/src/hackrf.c b/host/libhackrf/src/hackrf.c index e138cb879..728f8961b 100644 --- a/host/libhackrf/src/hackrf.c +++ b/host/libhackrf/src/hackrf.c @@ -2913,6 +2913,10 @@ extern ADDAPI const char* ADDCALL hackrf_board_rev_name(enum hackrf_board_rev bo case BOARD_REV_GSG_HACKRF1_R9: return "r9"; + case BOARD_REV_HACKRF1_R10: + case BOARD_REV_GSG_HACKRF1_R10: + return "r10"; + case BOARD_ID_UNRECOGNIZED: return "unrecognized"; diff --git a/host/libhackrf/src/hackrf.h b/host/libhackrf/src/hackrf.h index 7945fef27..ea8b1c6cd 100644 --- a/host/libhackrf/src/hackrf.h +++ b/host/libhackrf/src/hackrf.h @@ -714,6 +714,10 @@ enum hackrf_board_rev { * board revision 9, generic */ BOARD_REV_HACKRF1_R9 = 4, + /** + * board revision 10, generic + */ + BOARD_REV_HACKRF1_R10 = 5, /** * board revision 6, made by GSG @@ -731,6 +735,10 @@ enum hackrf_board_rev { * board revision 9, made by GSG */ BOARD_REV_GSG_HACKRF1_R9 = 0x84, + /** + * board revision 10, made by GSG + */ + BOARD_REV_GSG_HACKRF1_R10 = 0x85, /** * unknown board revision (detection failed)