Universalize: firmware/hackrf_usb

Co-authored-by: Antoine van Gelder <antoine@greatscottgadgets.com>
This commit is contained in:
Martin Ling 2026-04-04 01:12:34 +01:00
parent b6bbb393a2
commit 6a6d5d3acf
12 changed files with 451 additions and 203 deletions

View file

@ -46,23 +46,22 @@
#include <usb_request.h>
#include <usb_standard_request.h>
#include <usb_type.h>
#if !defined(RAD1O)
#include <mixer.h>
#endif
#if defined(PRALINE) || defined(HACKRF_ONE)
#if defined(PRALINE) || defined(HACKRF_ONE) || defined(UNIVERSAL)
#include <portapack.h>
#endif
#if defined(PRALINE) || defined(HACKRF_ONE) || defined(JAWBREAKER)
#if !defined(RAD1O)
#include <mixer.h>
#include <rffc5071.h>
#endif
#if defined(PRALINE)
#if defined(PRALINE) || defined(UNIVERSAL)
#include <fpga.h>
#if !(defined(DFU_MODE) || defined(RAM_MODE))
#include <lz4_buf.h>
#include <spi_bus.h>
#include <w25q80bv.h>
#endif
#else
#endif
#if !defined(PRALINE) || defined(UNIVERSAL)
#include <cpld_jtag.h>
#include <cpld_xc2c.h>
#endif
@ -80,9 +79,10 @@
#include "usb_descriptor.h"
#include "usb_device.h"
#include "usb_endpoint.h"
#if defined(PRALINE)
#if defined(PRALINE) || defined(UNIVERSAL)
#include "usb_api_praline.h"
#else
#endif
#if !defined(PRALINE) || defined(UNIVERSAL)
#include "usb_api_cpld.h"
#endif
@ -100,12 +100,12 @@ static usb_request_handler_fn vendor_request_handler[] = {
usb_vendor_request_read_si5351c,
usb_vendor_request_set_sample_rate_frac,
usb_vendor_request_set_baseband_filter_bandwidth,
#ifdef RAD1O
NULL, // write_rffc5071 not used
NULL, // read_rffc5071 not used
#else
#if !defined(RAD1O)
usb_vendor_request_write_rffc5071,
usb_vendor_request_read_rffc5071,
#else
NULL, // write_rffc5071 not used
NULL, // read_rffc5071 not used
#endif
usb_vendor_request_erase_spiflash,
usb_vendor_request_write_spiflash,
@ -120,7 +120,7 @@ static usb_request_handler_fn vendor_request_handler[] = {
usb_vendor_request_set_vga_gain,
usb_vendor_request_set_txvga_gain,
NULL, // was set_if_freq
#if (defined HACKRF_ONE || defined PRALINE)
#if defined(HACKRF_ONE) || defined(PRALINE) || defined(UNIVERSAL)
usb_vendor_request_set_antenna_enable,
#else
NULL,
@ -137,7 +137,7 @@ static usb_request_handler_fn vendor_request_handler[] = {
usb_vendor_request_spiflash_status,
usb_vendor_request_spiflash_clear_status,
usb_vendor_request_operacake_gpio_test,
#ifdef HACKRF_ONE
#if defined(HACKRF_ONE) || defined(UNIVERSAL)
usb_vendor_request_cpld_checksum,
#else
NULL,
@ -154,7 +154,7 @@ static usb_request_handler_fn vendor_request_handler[] = {
usb_vendor_request_read_supported_platform,
usb_vendor_request_set_leds,
usb_vendor_request_user_config_set_bias_t_opts,
#ifdef PRALINE
#if defined(PRALINE) || defined(UNIVERSAL)
usb_vendor_request_write_fpga_reg,
usb_vendor_request_read_fpga_reg,
usb_vendor_request_p2_ctrl,
@ -250,7 +250,7 @@ void usb_set_descriptor_by_serial_number(void)
}
}
#ifndef PRALINE
#if !defined(PRALINE) || defined(UNIVERSAL)
static bool cpld_jtag_sram_load(jtag_t* const jtag)
{
cpld_jtag_take(jtag);
@ -278,7 +278,7 @@ static void m0_rom_to_ram(void)
memcpy(dest, (uint32_t*) (base + src), len);
}
#if defined(PRALINE) && !(defined(DFU_MODE) || defined(RAM_MODE))
#if (defined(PRALINE) || defined(UNIVERSAL)) && !(defined(DFU_MODE) || defined(RAM_MODE))
extern uint32_t _binary_fpga_bin_start;
void fpga_loader_setup(void)
@ -311,73 +311,88 @@ int main(void)
// Detect hardware platform before we do anything else.
detect_hardware_platform();
board_id_t board_id = detected_platform();
pin_shutdown();
#ifndef RAD1O
clock_gen_shutdown();
#endif
if (board_id != BOARD_ID_RAD1O) {
clock_gen_shutdown();
}
delay_us_at_mhz(10000, 96);
pin_setup();
#ifndef PRALINE
enable_1v8_power();
#ifndef RAD1O
/*
* On rad1o, the clock generator power supply comes from the RF supply
* which is enabled later. On H1 and Jawbreaker, the clock generator is
* on the main 3V3 supply.
*/
clock_gen_init();
#endif
#else
enable_3v3aux_power();
if (board_id != BOARD_ID_PRALINE) {
enable_1v8_power();
if (board_id != BOARD_ID_RAD1O) {
/*
* On rad1o, the clock generator power supply comes from the RF supply
* which is enabled later. On H1 and Jawbreaker, the clock generator is
* on the main 3V3 supply.
*/
clock_gen_init();
}
} else {
#if defined(PRALINE) || defined(UNIVERSAL)
enable_3v3aux_power();
#if !defined(DFU_MODE) && !defined(RAM_MODE)
enable_1v2_power();
enable_rf_power();
/*
* On Praline, the clock generator power supply comes from 3V3FPGA
* which is enabled when 1V2FPGA is turned on.
*/
clock_gen_init();
enable_1v2_power();
enable_rf_power();
/*
* On Praline, the clock generator power supply comes from 3V3FPGA
* which is enabled when 1V2FPGA is turned on.
*/
clock_gen_init();
#endif
#endif
}
tuning_setup();
#ifdef HACKRF_ONE
// Set up mixer before enabling RF power, because its
// GPO is used to control the antenna bias tee.
mixer_setup(&mixer, RFFC5071_VARIANT);
if (board_id == BOARD_ID_HACKRF1_OG || board_id == BOARD_ID_HACKRF1_R9) {
#if defined(HACKRF_ONE) || defined(UNIVERSAL)
// Set up mixer before enabling RF power, because its
// GPO is used to control the antenna bias tee.
mixer_setup(&mixer, RFFC5071_VARIANT);
#endif
#if (defined HACKRF_ONE || defined RAD1O)
enable_rf_power();
#endif
#ifdef RAD1O
clock_gen_init();
}
if (board_id == BOARD_ID_HACKRF1_OG || board_id == BOARD_ID_HACKRF1_R9 ||
board_id == BOARD_ID_RAD1O) {
#if defined(RAD1O) || defined(HACKRF_ONE) || defined(UNIVERSAL)
enable_rf_power();
#endif
}
if (board_id == BOARD_ID_RAD1O) {
clock_gen_init();
}
cpu_clock_init();
/* Wake the M0 */
ipc_halt_m0();
ipc_start_m0((uint32_t) &__ram_m0_start__);
#ifndef PRALINE
if (!cpld_jtag_sram_load(&jtag_cpld)) {
halt_and_flash(6000000);
}
#else
#if defined(DFU_MODE) || defined(RAM_MODE)
selftest.fpga_image_load = SKIPPED;
selftest.report.pass = false;
#else
fpga_image_load(&fpga_loader, 0);
#endif
delay_us_at_mhz(100, 204);
fpga_spi_selftest();
fpga_sgpio_selftest();
if (board_id != BOARD_ID_PRALINE) {
#if !defined(PRALINE) || defined(UNIVERSAL)
if (!cpld_jtag_sram_load(&jtag_cpld)) {
halt_and_flash(6000000);
}
#endif
} else {
#if defined(PRALINE) || defined(UNIVERSAL)
#if defined(DFU_MODE) || defined(RAM_MODE)
selftest.fpga_image_load = SKIPPED;
selftest.report.pass = false;
#else
fpga_image_load(&fpga_loader, 0);
#endif
delay_us_at_mhz(100, 204);
fpga_spi_selftest();
fpga_sgpio_selftest();
#endif
}
radio_init(&radio);
#if (defined HACKRF_ONE || defined PRALINE)
portapack_init();
if (board_id == BOARD_ID_HACKRF1_OG || board_id == BOARD_ID_HACKRF1_R9 ||
board_id == BOARD_ID_PRALINE) {
#if defined(HACKRF_ONE) || defined(PRALINE) || defined(UNIVERSAL)
portapack_init();
#endif
}
#ifndef DFU_MODE
usb_set_descriptor_by_serial_number();
@ -386,6 +401,35 @@ int main(void)
usb_set_configuration_changed_cb(usb_configuration_changed);
usb_peripheral_reset();
switch (detected_platform()) {
case BOARD_ID_HACKRF1_OG:
case BOARD_ID_HACKRF1_R9:
#if defined(HACKRF_ONE) || defined(UNIVERSAL)
memcpy(&usb_device,
&usb_device_hackrf_one,
sizeof(usb_device_hackrf_one));
#endif
break;
case BOARD_ID_JAWBREAKER:
#if defined(JAWBREAKER)
memcpy(&usb_device,
&usb_device_jawbreaker,
sizeof(usb_device_jawbreaker));
#endif
break;
case BOARD_ID_RAD1O:
#if defined(RAD1O)
memcpy(&usb_device, &usb_device_rad1o, sizeof(usb_device_rad1o));
#endif
break;
case BOARD_ID_PRALINE:
#if defined(PRALINE) || defined(UNIVERSAL)
memcpy(&usb_device, &usb_device_praline, sizeof(usb_device_praline));
#endif
break;
default:
break;
};
usb_device_init(0, &usb_device);
usb_queue_init(&usb_endpoint_control_out_queue);
@ -404,13 +448,15 @@ int main(void)
rf_path_init(&rf_path);
#ifndef RAD1O
#if !defined(RAD1O)
rffc5071_lock_test(&mixer.rffc5071);
#endif
#ifdef PRALINE
fpga_if_xcvr_selftest();
if (board_id == BOARD_ID_PRALINE) {
#if defined(PRALINE) || defined(UNIVERSAL)
fpga_if_xcvr_selftest();
#endif
}
if (da7219_detect()) {
operacake_skip_i2c_address(DA7219_ADDRESS);
@ -456,11 +502,13 @@ int main(void)
case TRANSCEIVER_MODE_RX_SWEEP:
sweep_mode(request.seq);
break;
#ifndef PRALINE
case TRANSCEIVER_MODE_CPLD_UPDATE:
cpld_update();
break;
if (board_id != BOARD_ID_PRALINE) {
#if !defined(PRALINE) || defined(UNIVERSAL)
cpld_update();
#endif
}
break;
default:
break;
}

View file

@ -34,7 +34,7 @@
#include <usb_queue.h>
#include <usb_request.h>
#include <usb_type.h>
#ifdef HACKRF_ONE
#if defined(HACKRF_ONE) || defined(UNIVERSAL)
#include <gpio.h>
#include <platform_gpio.h>
#endif
@ -131,18 +131,19 @@ usb_request_status_t usb_vendor_request_reset(
if (stage == USB_TRANSFER_STAGE_SETUP) {
pin_shutdown();
clock_gen_shutdown();
#ifdef HACKRF_ONE
/*
* Set boot pins as inputs so that the bootloader reads them
* correctly after the reset.
*/
if (detected_platform() == BOARD_ID_HACKRF1_R9) {
#if defined(HACKRF_ONE) || defined(UNIVERSAL)
/*
* Set boot pins as inputs so that the bootloader reads them
* correctly after the reset.
*/
const platform_gpio_t* gpio = platform_gpio();
gpio_input(gpio->h1r9_mcu_clk_en);
gpio_input(gpio->h1r9_clkout_en);
gpio_input(gpio->h1r9_rx);
}
#endif
}
wwdt_reset(100000);
usb_transfer_schedule_ack(endpoint->in);

View file

@ -30,6 +30,7 @@
#include <cpld_jtag.h>
#include <cpld_xc2c.h>
#include <hackrf_core.h>
#include <platform_detect.h>
#include <usb_queue.h>
#include <usb_request.h>
#include <usb_type.h>
@ -90,6 +91,15 @@ usb_request_status_t usb_vendor_request_cpld_checksum(
static uint32_t cpld_crc;
uint8_t length;
switch (detected_platform()) {
case BOARD_ID_HACKRF1_OG:
case BOARD_ID_HACKRF1_R9:
// supported
break;
default:
return USB_REQUEST_STATUS_STALL;
}
if (stage == USB_TRANSFER_STAGE_SETUP) {
cpld_jtag_take(&jtag_cpld);
const bool checksum_success = cpld_xc2c64a_jtag_checksum(

View file

@ -24,6 +24,7 @@
#include "usb_api_praline.h"
#include <hackrf_core.h>
#include <platform_detect.h>
#include <usb_queue.h>
#include <usb_request.h>
#include <usb_type.h>
@ -35,6 +36,10 @@ usb_request_status_t usb_vendor_request_p1_ctrl(
usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage)
{
if (detected_platform() != BOARD_ID_PRALINE) {
return USB_REQUEST_STATUS_STALL;
}
if (stage == USB_TRANSFER_STAGE_SETUP) {
p1_ctrl_set(endpoint->setup.value);
usb_transfer_schedule_ack(endpoint->in);
@ -46,6 +51,10 @@ usb_request_status_t usb_vendor_request_p2_ctrl(
usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage)
{
if (detected_platform() != BOARD_ID_PRALINE) {
return USB_REQUEST_STATUS_STALL;
}
if (stage == USB_TRANSFER_STAGE_SETUP) {
p2_ctrl_set(endpoint->setup.value);
usb_transfer_schedule_ack(endpoint->in);
@ -57,6 +66,10 @@ usb_request_status_t usb_vendor_request_clkin_ctrl(
usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage)
{
if (detected_platform() != BOARD_ID_PRALINE) {
return USB_REQUEST_STATUS_STALL;
}
if (stage == USB_TRANSFER_STAGE_SETUP) {
clkin_ctrl_set(endpoint->setup.value & 1);
usb_transfer_schedule_ack(endpoint->in);
@ -68,6 +81,10 @@ usb_request_status_t usb_vendor_request_set_narrowband_filter(
usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage)
{
if (detected_platform() != BOARD_ID_PRALINE) {
return USB_REQUEST_STATUS_STALL;
}
if (stage == USB_TRANSFER_STAGE_SETUP) {
narrowband_filter_set(endpoint->setup.value);
usb_transfer_schedule_ack(endpoint->in);
@ -86,6 +103,10 @@ usb_request_status_t usb_vendor_request_set_fpga_bitstream(
#else
extern struct fpga_loader_t fpga_loader;
if (detected_platform() != BOARD_ID_PRALINE) {
return USB_REQUEST_STATUS_STALL;
}
if (stage == USB_TRANSFER_STAGE_SETUP) {
if (!fpga_image_load(&fpga_loader, endpoint->setup.value)) {
return USB_REQUEST_STATUS_STALL;

View file

@ -56,7 +56,7 @@ usb_request_status_t usb_vendor_request_set_leds(
usb_request_status_t usb_vendor_request_user_config_set_bias_t_opts(
usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage);
#ifdef PRALINE
#if defined(PRALINE) || defined(UNIVERSAL)
usb_request_status_t usb_vendor_request_write_fpga_reg(
usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage);

View file

@ -21,20 +21,18 @@
#include <stddef.h>
#include <stdint.h>
#if defined(PRALINE) || defined(HACKRF_ONE) || defined(JAWBREAKER)
#if !defined(RAD1O)
#include <stdbool.h>
#endif
#include <libopencm3/lpc43xx/cgu.h>
#include <libopencm3/lpc43xx/creg.h>
#include <platform_detect.h>
#include <selftest.h>
#include <usb_queue.h>
#include <usb_request.h>
#include <usb_type.h>
#if !defined(PRALINE)
#include <platform_detect.h>
#endif
#include "usb_api_selftest.h"
@ -63,7 +61,7 @@ void append(char** dest, size_t* capacity, const char* str)
}
}
#ifdef PRALINE
#if defined(PRALINE) || defined(UNIVERSAL)
static const char* test_result_to_str(test_result_t result)
{
switch (result) {
@ -82,91 +80,105 @@ static const char* test_result_to_str(test_result_t result)
void generate_selftest_report(void)
{
board_id_t board_id = detected_platform();
char* s = &selftest.report.msg[0];
size_t c = sizeof(selftest.report.msg);
#ifdef RAD1O
append(&s, &c, "Mixer: MAX2871, ID: ");
append(&s, &c, itoa(selftest.mixer_id, 10));
append(&s, &c, "\n");
#else
append(&s, &c, "Mixer: RFFC5072, ID: ");
append(&s, &c, itoa(selftest.mixer_id >> 3, 10));
append(&s, &c, ", Rev: ");
append(&s, &c, itoa(selftest.mixer_id & 0x7, 10));
append(&s, &c, ", Locks: ");
bool lock;
for (int i = 0; i < NUM_LOCK_ATTEMPTS; i++) {
lock = selftest.mixer_locks[i];
append(&s, &c, itoa(lock, 2));
}
if (lock) {
append(&s, &c, " (PASS)");
} else {
append(&s, &c, " (FAIL)");
}
append(&s, &c, "\n");
if (board_id == BOARD_ID_RAD1O) {
#if defined(RAD1O)
append(&s, &c, "Mixer: MAX2871, ID: ");
append(&s, &c, itoa(selftest.mixer_id, 10));
append(&s, &c, "\n");
#endif
} else {
#if !defined(RAD1O)
append(&s, &c, "Mixer: RFFC5072, ID: ");
append(&s, &c, itoa(selftest.mixer_id >> 3, 10));
append(&s, &c, ", Rev: ");
append(&s, &c, itoa(selftest.mixer_id & 0x7, 10));
append(&s, &c, ", Locks: ");
bool lock;
for (int i = 0; i < NUM_LOCK_ATTEMPTS; i++) {
lock = selftest.mixer_locks[i];
append(&s, &c, itoa(lock, 2));
}
if (lock) {
append(&s, &c, " (PASS)");
} else {
append(&s, &c, " (FAIL)");
}
append(&s, &c, "\n");
#endif
}
append(&s, &c, "Clock: Si5351");
append(&s, &c, ", Rev: ");
append(&s, &c, itoa(selftest.si5351_rev_id, 10));
append(&s, &c, ", readback: ");
append(&s, &c, selftest.si5351_readback_ok ? "OK" : "FAIL");
append(&s, &c, "\n");
#ifdef PRALINE
append(&s, &c, "Transceiver: MAX2831, RSSI mux test: ");
append(&s, &c, selftest.max2831_mux_test_ok ? "PASS" : "FAIL");
append(&s, &c, "\n");
#else
append(&s, &c, "Transceiver: ");
append(&s,
&c,
(detected_platform() == BOARD_ID_HACKRF1_R9 ? "MAX2839" : "MAX2837"));
append(&s, &c, ", readback success: ");
append(&s, &c, itoa(selftest.max283x_readback_register_count, 10));
append(&s, &c, "/");
append(&s, &c, itoa(selftest.max283x_readback_total_registers, 10));
if (selftest.max283x_readback_register_count <
selftest.max283x_readback_total_registers) {
append(&s, &c, ", bad value: 0x");
append(&s, &c, itoa(selftest.max283x_readback_bad_value, 10));
append(&s, &c, ", expected: 0x");
append(&s, &c, itoa(selftest.max283x_readback_expected_value, 10));
}
append(&s, &c, "\n");
#endif
#ifdef PRALINE
append(&s, &c, "FPGA configuration: ");
append(&s, &c, test_result_to_str(selftest.fpga_image_load));
append(&s, &c, "\n");
append(&s, &c, "FPGA SPI: ");
append(&s, &c, test_result_to_str(selftest.fpga_spi));
append(&s, &c, "\n");
append(&s, &c, "SGPIO RX test: ");
append(&s, &c, test_result_to_str(selftest.sgpio_rx));
append(&s, &c, "\n");
append(&s, &c, "Loopback test: ");
append(&s, &c, test_result_to_str(selftest.xcvr_loopback));
append(&s, &c, "\n");
// Dump transceiver loopback measurements.
for (int i = 0; i < 4; ++i) {
struct xcvr_measurements* m = &selftest.xcvr_measurements[i];
append(&s, &c, " ");
append(&s, &c, itoa(i, 10));
append(&s, &c, ":");
append(&s, &c, itoa(m->zcs_i, 10));
append(&s, &c, ",");
append(&s, &c, itoa(m->zcs_q, 10));
append(&s, &c, ",");
append(&s, &c, itoa(m->max_mag_i, 10));
append(&s, &c, ",");
append(&s, &c, itoa(m->max_mag_q, 10));
append(&s, &c, ",");
append(&s, &c, itoa(m->avg_mag_sq_i, 10));
append(&s, &c, ",");
append(&s, &c, itoa(m->avg_mag_sq_q, 10));
if (board_id == BOARD_ID_PRALINE) {
#if defined(PRALINE) || defined(UNIVERSAL)
append(&s, &c, "Transceiver: MAX2831, RSSI mux test: ");
append(&s, &c, selftest.max2831_mux_test_ok ? "PASS" : "FAIL");
append(&s, &c, "\n");
}
#endif
} else {
#if !defined(PRALINE) || defined(UNIVERSAL)
append(&s, &c, "Transceiver: ");
append(&s, &c, (board_id == BOARD_ID_HACKRF1_R9 ? "MAX2839" : "MAX2837"));
append(&s, &c, ", readback success: ");
append(&s, &c, itoa(selftest.max283x_readback_register_count, 10));
append(&s, &c, "/");
append(&s, &c, itoa(selftest.max283x_readback_total_registers, 10));
if (selftest.max283x_readback_register_count <
selftest.max283x_readback_total_registers) {
append(&s, &c, ", bad value: 0x");
append(&s, &c, itoa(selftest.max283x_readback_bad_value, 10));
append(&s, &c, ", expected: 0x");
append(&s,
&c,
itoa(selftest.max283x_readback_expected_value, 10));
}
append(&s, &c, "\n");
#endif
}
if (board_id == BOARD_ID_PRALINE) {
#if defined(PRALINE) || defined(UNIVERSAL)
append(&s, &c, "FPGA configuration: ");
append(&s, &c, test_result_to_str(selftest.fpga_image_load));
append(&s, &c, "\n");
append(&s, &c, "FPGA SPI: ");
append(&s, &c, test_result_to_str(selftest.fpga_spi));
append(&s, &c, "\n");
append(&s, &c, "SGPIO RX test: ");
append(&s, &c, test_result_to_str(selftest.sgpio_rx));
append(&s, &c, "\n");
append(&s, &c, "Loopback test: ");
append(&s, &c, test_result_to_str(selftest.xcvr_loopback));
append(&s, &c, "\n");
// Dump transceiver loopback measurements.
for (int i = 0; i < 4; ++i) {
struct xcvr_measurements* m = &selftest.xcvr_measurements[i];
append(&s, &c, " ");
append(&s, &c, itoa(i, 10));
append(&s, &c, ":");
append(&s, &c, itoa(m->zcs_i, 10));
append(&s, &c, ",");
append(&s, &c, itoa(m->zcs_q, 10));
append(&s, &c, ",");
append(&s, &c, itoa(m->max_mag_i, 10));
append(&s, &c, ",");
append(&s, &c, itoa(m->max_mag_q, 10));
append(&s, &c, ",");
append(&s, &c, itoa(m->avg_mag_sq_i, 10));
append(&s, &c, ",");
append(&s, &c, itoa(m->avg_mag_sq_q, 10));
append(&s, &c, "\n");
}
#endif
}
}
usb_request_status_t usb_vendor_request_read_selftest(

View file

@ -29,6 +29,7 @@
#include <hackrf_core.h>
#include <hackrf_ui.h>
#include <m0_state.h>
#include <platform_detect.h>
#include <radio.h>
#include <rf_path.h>
#include <streaming.h>
@ -46,11 +47,6 @@
#define MAX(x, y) ((x) > (y) ? (x) : (y))
#define FREQ_GRANULARITY 1000000
#define MAX_RANGES 10
#ifndef PRALINE
#define THROWAWAY_BUFFERS 2
#else
#define THROWAWAY_BUFFERS 1
#endif
static uint64_t sweep_freq;
static uint16_t frequencies[MAX_RANGES * 2];
@ -59,6 +55,7 @@ static uint16_t num_ranges = 0;
static uint32_t dwell_blocks = 0;
static uint32_t step_width = 0;
static uint32_t offset = 0;
static uint32_t throwaway_buffers = 0;
static enum sweep_style style = LINEAR;
static bool freq_ui_dirty = false;
static bool img_reject_ui_dirty = false;
@ -91,6 +88,12 @@ usb_request_status_t usb_vendor_request_init_sweep(
usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage)
{
if (detected_platform() == BOARD_ID_PRALINE) {
throwaway_buffers = 1;
} else {
throwaway_buffers = 2;
}
uint32_t num_bytes;
int i;
if (stage == USB_TRANSFER_STAGE_SETUP) {
@ -144,7 +147,7 @@ void sweep_bulk_transfer_complete(void* user_data, unsigned int bytes_transferre
// For each buffer transferred, we need to bump the count to allow
// for the buffer(s) that are to be discarded.
m0_state.m4_count += (THROWAWAY_BUFFERS + 1) * 0x4000;
m0_state.m4_count += (throwaway_buffers + 1) * 0x4000;
}
void sweep_mode(uint32_t seq)
@ -200,7 +203,7 @@ void sweep_mode(uint32_t seq)
// Set M0 to switch back to RX after we have received our
// discard buffers.
m0_state.threshold += (0x4000 * THROWAWAY_BUFFERS);
m0_state.threshold += (0x4000 * throwaway_buffers);
m0_state.next_mode = M0_MODE_RX;
// Write metadata to buffer.
@ -225,7 +228,7 @@ void sweep_mode(uint32_t seq)
NULL);
// Use other buffer next time.
phase = (phase + 1) % THROWAWAY_BUFFERS;
phase = (phase + 1) % throwaway_buffers;
if (++blocks_queued == dwell_blocks) {
// Calculate next sweep frequency.

View file

@ -31,6 +31,7 @@
#include <hackrf_ui.h>
#include <m0_state.h>
#include <operacake_sctimer.h>
#include <platform_detect.h>
#include <radio.h>
#include <streaming.h>
#include <transceiver_mode.h>
@ -287,6 +288,16 @@ usb_request_status_t usb_vendor_request_set_antenna_enable(
usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage)
{
switch (detected_platform()) {
case BOARD_ID_HACKRF1_OG:
case BOARD_ID_HACKRF1_R9:
case BOARD_ID_PRALINE:
// supported
break;
default:
return USB_REQUEST_STATUS_STALL;
}
if (stage == USB_TRANSFER_STAGE_SETUP) {
radio_reg_write(
&radio,

View file

@ -51,7 +51,8 @@
#define USB_STRING_LANGID (0x0409)
uint8_t usb_descriptor_device[] = {
#if defined(HACKRF_ONE) || defined(PRALINE) || defined(UNIVERSAL)
uint8_t usb_descriptor_device_hackrf[] = {
18, // bLength
USB_DESCRIPTOR_TYPE_DEVICE, // bDescriptorType
USB_WORD(0x0200), // bcdUSB
@ -60,13 +61,50 @@ uint8_t usb_descriptor_device[] = {
0x00, // bDeviceProtocol
USB_MAX_PACKET0, // bMaxPacketSize0
USB_WORD(USB_VENDOR_ID), // idVendor
USB_WORD(USB_PRODUCT_ID), // idProduct
USB_WORD(0x6089), // idProduct
USB_WORD(USB_API_VERSION), // bcdDevice
0x01, // iManufacturer
0x02, // iProduct
0x04, // iSerialNumber
0x01 // bNumConfigurations
};
#endif
#if defined(JAWBREAKER)
uint8_t usb_descriptor_device_jawbreaker[] = {
18, // bLength
USB_DESCRIPTOR_TYPE_DEVICE, // bDescriptorType
USB_WORD(0x0200), // bcdUSB
0x00, // bDeviceClass
0x00, // bDeviceSubClass
0x00, // bDeviceProtocol
USB_MAX_PACKET0, // bMaxPacketSize0
USB_WORD(USB_VENDOR_ID), // idVendor
USB_WORD(0x604B), // idProduct
USB_WORD(USB_API_VERSION), // bcdDevice
0x01, // iManufacturer
0x02, // iProduct
0x04, // iSerialNumber
0x01 // bNumConfigurations
};
#endif
#if defined(RAD1O)
uint8_t usb_descriptor_device_rad1o[] = {
18, // bLength
USB_DESCRIPTOR_TYPE_DEVICE, // bDescriptorType
USB_WORD(0x0200), // bcdUSB
0x00, // bDeviceClass
0x00, // bDeviceSubClass
0x00, // bDeviceProtocol
USB_MAX_PACKET0, // bMaxPacketSize0
USB_WORD(USB_VENDOR_ID), // idVendor
USB_WORD(0xCC15), // idProduct
USB_WORD(USB_API_VERSION), // bcdDevice
0x01, // iManufacturer
0x02, // iProduct
0x04, // iSerialNumber
0x01 // bNumConfigurations
};
#endif
uint8_t usb_descriptor_device_qualifier[] = {
10, // bLength
@ -185,8 +223,8 @@ uint8_t usb_descriptor_string_manufacturer[] = {
's', 0x00,
};
uint8_t usb_descriptor_string_product[] = {
#ifdef HACKRF_ONE
#if defined(HACKRF_ONE) || defined(UNIVERSAL)
uint8_t usb_descriptor_string_product_hackrf_one[] = {
22, // bLength
USB_DESCRIPTOR_TYPE_STRING, // bDescriptorType
'H', 0x00,
@ -199,7 +237,26 @@ uint8_t usb_descriptor_string_product[] = {
'O', 0x00,
'n', 0x00,
'e', 0x00,
#elif JAWBREAKER
};
#endif
#if defined(PRALINE) || defined(UNIVERSAL)
uint8_t usb_descriptor_string_product_praline[] = {
22, // bLength
USB_DESCRIPTOR_TYPE_STRING, // bDescriptorType
'H', 0x00,
'a', 0x00,
'c', 0x00,
'k', 0x00,
'R', 0x00,
'F', 0x00,
' ', 0x00,
'P', 0x00,
'r', 0x00,
'o', 0x00,
};
#endif
#if defined(JAWBREAKER)
uint8_t usb_descriptor_string_product_jawbreaker[] = {
36, // bLength
USB_DESCRIPTOR_TYPE_STRING, // bDescriptorType
'H', 0x00,
@ -219,7 +276,10 @@ uint8_t usb_descriptor_string_product[] = {
'k', 0x00,
'e', 0x00,
'r', 0x00,
#elif RAD1O
};
#endif
#if defined(RAD1O)
uint8_t usb_descriptor_string_product_rad1o[] = {
12, // bLength
USB_DESCRIPTOR_TYPE_STRING, // bDescriptorType
'r', 0x00,
@ -227,30 +287,8 @@ uint8_t usb_descriptor_string_product[] = {
'd', 0x00,
'1', 0x00,
'o', 0x00,
#elif PRALINE
22, // bLength
USB_DESCRIPTOR_TYPE_STRING, // bDescriptorType
'H', 0x00,
'a', 0x00,
'c', 0x00,
'k', 0x00,
'R', 0x00,
'F', 0x00,
' ', 0x00,
'P', 0x00,
'r', 0x00,
'o', 0x00,
#else
14, // bLength
USB_DESCRIPTOR_TYPE_STRING, // bDescriptorType
'H', 0x00,
'a', 0x00,
'c', 0x00,
'k', 0x00,
'R', 0x00,
'F', 0x00,
#endif
};
#endif
uint8_t usb_descriptor_string_config_description[] = {
24, // bLength
@ -291,14 +329,46 @@ uint8_t usb_descriptor_string_serial_number[] = {
uint8_t usb_descriptor_string_serial_number[USB_DESCRIPTOR_STRING_SERIAL_BUF_LEN];
#endif
uint8_t* usb_descriptor_strings[] = {
#if defined(HACKRF_ONE) || defined(UNIVERSAL)
uint8_t* usb_descriptor_strings_hackrf_one[] = {
usb_descriptor_string_languages,
usb_descriptor_string_manufacturer,
usb_descriptor_string_product,
usb_descriptor_string_product_hackrf_one,
usb_descriptor_string_config_description,
usb_descriptor_string_serial_number,
0, // TERMINATOR
};
#endif
#if defined(PRALINE) || defined(UNIVERSAL)
uint8_t* usb_descriptor_strings_praline[] = {
usb_descriptor_string_languages,
usb_descriptor_string_manufacturer,
usb_descriptor_string_product_praline,
usb_descriptor_string_config_description,
usb_descriptor_string_serial_number,
0, // TERMINATOR
};
#endif
#if defined(JAWBREAKER)
uint8_t* usb_descriptor_strings_jawbreaker[] = {
usb_descriptor_string_languages,
usb_descriptor_string_manufacturer,
usb_descriptor_string_product_jawbreaker,
usb_descriptor_string_config_description,
usb_descriptor_string_serial_number,
0, // TERMINATOR
};
#endif
#if defined(RAD1O)
uint8_t* usb_descriptor_strings_rad1o[] = {
usb_descriptor_string_languages,
usb_descriptor_string_manufacturer,
usb_descriptor_string_product_rad1o,
usb_descriptor_string_config_description,
usb_descriptor_string_serial_number,
0, // TERMINATOR
};
#endif
uint8_t wcid_string_descriptor[] = {
18, // bLength

View file

@ -24,20 +24,42 @@
#include <stdint.h>
extern uint8_t usb_descriptor_device[];
#if defined(HACKRF_ONE) || defined(PRALINE) || defined(UNIVERSAL)
extern uint8_t usb_descriptor_device_hackrf[];
#endif
#if defined(JAWBREAKER)
extern uint8_t usb_descriptor_device_jawbreaker[];
#endif
#if defined(RAD1O)
extern uint8_t usb_descriptor_device_rad1o[];
#endif
extern uint8_t usb_descriptor_device_qualifier[];
extern uint8_t usb_descriptor_configuration_full_speed[];
extern uint8_t usb_descriptor_configuration_high_speed[];
extern uint8_t usb_descriptor_string_languages[];
extern uint8_t usb_descriptor_string_manufacturer[];
extern uint8_t usb_descriptor_string_product[];
#if defined(HACKRF_ONE) || defined(UNIVERSAL)
extern uint8_t usb_descriptor_string_product_hackrf_one[];
#endif
#if defined(PRALINE) || defined(UNIVERSAL)
extern uint8_t usb_descriptor_string_product_praline[];
#endif
#if defined(JAWBREAKER)
extern uint8_t usb_descriptor_string_product_jawbreaker[];
#endif
#if defined(RAD1O)
extern uint8_t usb_descriptor_string_product_rad1o[];
#endif
#define USB_DESCRIPTOR_STRING_SERIAL_LEN 32
#define USB_DESCRIPTOR_STRING_SERIAL_BUF_LEN \
(USB_DESCRIPTOR_STRING_SERIAL_LEN * 2 + 2) /* UTF-16LE */
extern uint8_t usb_descriptor_string_serial_number[];
extern uint8_t* usb_descriptor_strings[];
extern uint8_t* usb_descriptor_strings_hackrf_one[];
extern uint8_t* usb_descriptor_strings_jawbreaker[];
extern uint8_t* usb_descriptor_strings_rad1o[];
extern uint8_t* usb_descriptor_strings_praline[];
#define USB_WCID_VENDOR_REQ 0x19
extern uint8_t wcid_string_descriptor[];

View file

@ -45,12 +45,49 @@ usb_configuration_t* usb_configurations[] = {
0,
};
usb_device_t usb_device = {
.descriptor = usb_descriptor_device,
.descriptor_strings = usb_descriptor_strings,
usb_device_t usb_device;
#if defined(HACKRF_ONE) || defined(UNIVERSAL)
const usb_device_t usb_device_hackrf_one = {
.descriptor = usb_descriptor_device_hackrf,
.descriptor_strings = usb_descriptor_strings_hackrf_one,
.qualifier_descriptor = usb_descriptor_device_qualifier,
.configurations = &usb_configurations,
.configuration = 0,
.wcid_string_descriptor = wcid_string_descriptor,
.wcid_feature_descriptor = wcid_feature_descriptor,
};
#endif
#if defined(PRALINE) || defined(UNIVERSAL)
const usb_device_t usb_device_praline = {
.descriptor = usb_descriptor_device_hackrf,
.descriptor_strings = usb_descriptor_strings_praline,
.qualifier_descriptor = usb_descriptor_device_qualifier,
.configurations = &usb_configurations,
.configuration = 0,
.wcid_string_descriptor = wcid_string_descriptor,
.wcid_feature_descriptor = wcid_feature_descriptor,
};
#endif
#if defined(JAWBREAKER)
const usb_device_t usb_device_jawbreaker = {
.descriptor = usb_descriptor_device_jawbreaker,
.descriptor_strings = usb_descriptor_strings_jawbreaker,
.qualifier_descriptor = usb_descriptor_device_qualifier,
.configurations = &usb_configurations,
.configuration = 0,
.wcid_string_descriptor = wcid_string_descriptor,
.wcid_feature_descriptor = wcid_feature_descriptor,
};
#endif
#if defined(RAD1O)
const usb_device_t usb_device_rad1o = {
.descriptor = usb_descriptor_device_rad1o,
.descriptor_strings = usb_descriptor_strings_rad1o,
.qualifier_descriptor = usb_descriptor_device_qualifier,
.configurations = &usb_configurations,
.configuration = 0,
.wcid_string_descriptor = wcid_string_descriptor,
.wcid_feature_descriptor = wcid_feature_descriptor,
};
#endif

View file

@ -26,3 +26,16 @@
#include <usb_type.h>
extern usb_device_t usb_device;
#if defined(HACKRF_ONE) || defined(UNIVERSAL)
extern const usb_device_t usb_device_hackrf_one;
#endif
#if defined(PRALINE) || defined(UNIVERSAL)
extern const usb_device_t usb_device_praline;
#endif
#if defined(JAWBREAKER)
extern const usb_device_t usb_device_jawbreaker;
#endif
#if defined(RAD1O)
extern const usb_device_t usb_device_rad1o;
#endif