Merge pull request #1418 from greatscottgadgets/h1r10-fw

Support detection of HackRF One r10
This commit is contained in:
Michael Ossmann
2024-02-22 10:52:35 -05:00
committed by GitHub
4 changed files with 92 additions and 43 deletions

View File

@ -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_led2 = GPIO(2, 2);
static struct gpio_t gpio_led3 = GPIO(2, 8); 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; pin &= 0x7;
uint8_t pin_mask = (1 << pin); uint8_t pin_mask = (1 << pin);
ADC0_CR = ADC_CR_SEL(pin_mask) | ADC_CR_CLKDIV(45) | ADC_CR_CLKS(2) | ADC_CR_PDN | ADC0_CR = ADC_CR_SEL(pin_mask) | ADC_CR_CLKDIV(45) | ADC_CR_PDN | ADC_CR_START(1);
ADC_CR_START(1);
while (!(ADC0_GDR & ADC_DR_DONE) || (((ADC0_GDR >> 24) & 0x7) != pin)) {} while (!(ADC0_GDR & ADC_DR_DONE) || (((ADC0_GDR >> 24) & 0x7) != pin)) {}
return (ADC0_GDR >> 6) & 0x03FF; return (ADC0_GDR >> 6) & 0x03FF;
} }
@ -81,16 +83,14 @@ void adc_off(void)
* the unconnected state by averaging several ADC readings. * the unconnected state by averaging several ADC readings.
*/ */
#define NUM_SAMPLES (10) #define NUM_SAMPLES (10)
#define LOW_THRESHOLD (2 * NUM_SAMPLES) #define LOW_THRESHOLD (2)
#define HIGH_THRESHOLD (253 * NUM_SAMPLES) #define HIGH_THRESHOLD (1022)
typedef enum { #define HIGH(x) ((x) > HIGH_THRESHOLD)
PIN_STRAP_HIGH, #define LOW(x) ((x) < LOW_THRESHOLD)
PIN_STRAP_LOW, #define ABSENT(x) (((x) >= LOW_THRESHOLD) && ((x) <= HIGH_THRESHOLD))
PIN_STRAP_ABSENT,
} pin_strap_t;
pin_strap_t check_pin_strap(uint8_t pin) uint32_t check_pin_strap(uint8_t pin)
{ {
int i; int i;
uint32_t sum = 0; uint32_t sum = 0;
@ -99,15 +99,53 @@ pin_strap_t check_pin_strap(uint8_t pin)
sum += adc_read(pin); sum += adc_read(pin);
} }
adc_off(); adc_off();
if (sum > HIGH_THRESHOLD) { return (sum / NUM_SAMPLES);
return PIN_STRAP_HIGH;
} else if (sum < LOW_THRESHOLD) {
return PIN_STRAP_LOW;
} else {
return PIN_STRAP_ABSENT;
}
} }
/*
* 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) void detect_hardware_platform(void)
{ {
uint8_t detected_resistors = 0; uint8_t detected_resistors = 0;
@ -175,34 +213,31 @@ void detect_hardware_platform(void)
halt_and_flash(1000000); halt_and_flash(1000000);
} }
pin_strap_t adc0_3 = check_pin_strap(3); uint32_t adc0_3 = check_pin_strap(3);
pin_strap_t adc0_4 = check_pin_strap(4); uint32_t adc0_4 = check_pin_strap(4);
pin_strap_t adc0_7 = check_pin_strap(7); uint32_t adc0_7 = check_pin_strap(7);
if ((adc0_3 == PIN_STRAP_ABSENT) && (adc0_4 == PIN_STRAP_ABSENT) && if (platform == BOARD_ID_HACKRF1_OG) {
(adc0_7 == PIN_STRAP_ABSENT) && (platform == BOARD_ID_HACKRF1_OG)) { if (ABSENT(adc0_3) && ABSENT(adc0_4) && ABSENT(adc0_7)) {
revision = BOARD_REV_HACKRF1_OLD; revision = BOARD_REV_HACKRF1_OLD;
} else if ( } else if (HIGH(adc0_3) && HIGH(adc0_4)) {
(adc0_3 == PIN_STRAP_HIGH) && (adc0_4 == PIN_STRAP_HIGH) && revision = BOARD_REV_HACKRF1_R6;
(platform == BOARD_ID_HACKRF1_OG)) { } else if (LOW(adc0_3) && HIGH(adc0_4)) {
revision = BOARD_REV_HACKRF1_R6; revision = BOARD_REV_HACKRF1_R7;
} else if ( } else if (LOW(adc0_4)) {
(adc0_3 == PIN_STRAP_LOW) && (adc0_4 == PIN_STRAP_HIGH) && revision = revision_from_adc[adc0_3 >> 5];
(platform == BOARD_ID_HACKRF1_OG)) { } else {
revision = BOARD_REV_HACKRF1_R7; revision = BOARD_REV_UNRECOGNIZED;
} else if ( }
(adc0_3 == PIN_STRAP_HIGH) && (adc0_4 == PIN_STRAP_LOW) && } else if (platform == BOARD_ID_HACKRF1_R9) {
(platform == BOARD_ID_HACKRF1_OG)) { if (LOW(adc0_3) && LOW(adc0_4)) {
revision = BOARD_REV_HACKRF1_R8; revision = BOARD_REV_HACKRF1_R9;
} else if ( } else {
(adc0_3 == PIN_STRAP_LOW) && (adc0_4 == PIN_STRAP_LOW) && revision = BOARD_REV_UNRECOGNIZED;
(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)) { if ((revision > BOARD_REV_HACKRF1_OLD) && LOW(adc0_7)) {
revision |= BOARD_REV_GSG; revision |= BOARD_REV_GSG;
} }
} }

View File

@ -47,10 +47,12 @@ typedef enum {
BOARD_REV_HACKRF1_R7 = 2, BOARD_REV_HACKRF1_R7 = 2,
BOARD_REV_HACKRF1_R8 = 3, BOARD_REV_HACKRF1_R8 = 3,
BOARD_REV_HACKRF1_R9 = 4, BOARD_REV_HACKRF1_R9 = 4,
BOARD_REV_HACKRF1_R10 = 5,
BOARD_REV_GSG_HACKRF1_R6 = 0x81, BOARD_REV_GSG_HACKRF1_R6 = 0x81,
BOARD_REV_GSG_HACKRF1_R7 = 0x82, BOARD_REV_GSG_HACKRF1_R7 = 0x82,
BOARD_REV_GSG_HACKRF1_R8 = 0x83, BOARD_REV_GSG_HACKRF1_R8 = 0x83,
BOARD_REV_GSG_HACKRF1_R9 = 0x84, BOARD_REV_GSG_HACKRF1_R9 = 0x84,
BOARD_REV_GSG_HACKRF1_R10 = 0x85,
BOARD_REV_UNRECOGNIZED = BOARD_REV_UNRECOGNIZED =
0xFE, /* tried detection but did not recognize revision */ 0xFE, /* tried detection but did not recognize revision */
BOARD_REV_UNDETECTED = 0xFF, /* detection not yet attempted */ BOARD_REV_UNDETECTED = 0xFF, /* detection not yet attempted */

View File

@ -2913,6 +2913,10 @@ extern ADDAPI const char* ADDCALL hackrf_board_rev_name(enum hackrf_board_rev bo
case BOARD_REV_GSG_HACKRF1_R9: case BOARD_REV_GSG_HACKRF1_R9:
return "r9"; return "r9";
case BOARD_REV_HACKRF1_R10:
case BOARD_REV_GSG_HACKRF1_R10:
return "r10";
case BOARD_ID_UNRECOGNIZED: case BOARD_ID_UNRECOGNIZED:
return "unrecognized"; return "unrecognized";

View File

@ -714,6 +714,10 @@ enum hackrf_board_rev {
* board revision 9, generic * board revision 9, generic
*/ */
BOARD_REV_HACKRF1_R9 = 4, BOARD_REV_HACKRF1_R9 = 4,
/**
* board revision 10, generic
*/
BOARD_REV_HACKRF1_R10 = 5,
/** /**
* board revision 6, made by GSG * board revision 6, made by GSG
@ -731,6 +735,10 @@ enum hackrf_board_rev {
* board revision 9, made by GSG * board revision 9, made by GSG
*/ */
BOARD_REV_GSG_HACKRF1_R9 = 0x84, BOARD_REV_GSG_HACKRF1_R9 = 0x84,
/**
* board revision 10, made by GSG
*/
BOARD_REV_GSG_HACKRF1_R10 = 0x85,
/** /**
* unknown board revision (detection failed) * unknown board revision (detection failed)