Update hackrf submodule (#3174)

* updated submodule

* usb_serial: populate usb_device before usb_run. Upstream now leaves the global usb_device zero-initialized and expects hackrf_usb.c to memcpy a per-board const into it. We don't link hackrf_usb.c, so do the memcpy here. Also flip control_in to enable_zlp=true to match the new endpoint API.

* baseband: derive IS_* board defines from BOARD. Upstream moved platform IS_* macros from platform_detect.h to cmake. Set them per BOARD here since we don't include platform-detect.cmake. Drop the duplicate clkin.c entry.

* sd_over_usb: drop duplicate driver objects, fix setup callback. Upstream now defines i2c0/i2c1, spi_bus_ssp0/1, sgpio_config and rf_path in the common driver files, so stop redefining them here and patch the runtime fields in pin_setup() instead. Update si5351c_reset_pll() call to the two-arg form. Replace the no-op transceiver_usb_setup_complete stub with one that delegates to usb_setup_complete.

* sd_over_usb: populate usb_device before usb_run. Same fix as the application side: memcpy a const template into usb_device before usb_device_init/usb_run, otherwise the descriptor pointer is NULL. Also pass enable_zlp=true on control_in to match the new endpoint API.

* fix unicode in comment

* remove lz4 bufs reservation in M0
This commit is contained in:
gullradriel
2026-05-13 14:53:54 +02:00
committed by GitHub
parent c34a6940ca
commit 95d246a020
5 changed files with 152 additions and 83 deletions
+28 -1
View File
@@ -20,9 +20,31 @@
*/
#include "usb_serial_cdc.h"
#include "usb_serial_descriptor.h"
#include "usb_serial_endpoints.h"
#include "usb_serial_event.hpp"
#include <string.h>
/* Defined in hackrf/firmware/hackrf_usb/usb_device.c. After upstream commit
* 85dfacf6 ("Universalize: firmware/hackrf_usb"), the global `usb_device` is
* left zero-initialized and is populated at runtime from per-board
* `usb_device_*` constants inside hackrf_usb.c. Mayhem does not link
* hackrf_usb.c, so we must populate `usb_device` ourselves before usb_run().
* The descriptor fields are const-qualified, so we follow the upstream
* pattern of memcpy from a const template. */
extern usb_configuration_t* usb_configurations[];
static const usb_device_t usb_device_mayhem = {
.descriptor = usb_descriptor_device,
.descriptor_strings = usb_descriptor_strings,
.qualifier_descriptor = usb_descriptor_device_qualifier,
.configurations = &usb_configurations,
.configuration = 0,
.wcid_string_descriptor = wcid_string_descriptor,
.wcid_feature_descriptor = wcid_feature_descriptor,
};
uint32_t EVT_MASK_USB = EVENT_MASK(8);
extern void usb0_isr(void);
@@ -85,6 +107,8 @@ void usb_configuration_changed(usb_device_t* const device) {
}
void setup_usb_serial_controller(void) {
memcpy(&usb_device, &usb_device_mayhem, sizeof(usb_device_mayhem));
usb_set_configuration_changed_cb(usb_configuration_changed);
usb_peripheral_reset();
@@ -97,7 +121,10 @@ void setup_usb_serial_controller(void) {
usb_queue_init(&usb_endpoint_bulk_in_queue);
usb_endpoint_init(&usb_endpoint_control_out, false);
usb_endpoint_init(&usb_endpoint_control_in, false);
/* Control IN needs ZLP for descriptor reads whose length is a multiple of
* the max packet size (otherwise the host hangs waiting for the transfer
* to terminate). Matches upstream hackrf_usb.c after commit db73ecbf. */
usb_endpoint_init(&usb_endpoint_control_in, true);
usb_run(&usb_device);
}
+19 -3
View File
@@ -217,7 +217,25 @@ set(CPPWARN "-Wall -Wextra")
if(NOT DEFINED BOARD)
set(BOARD "HACKRF_ONE")
endif()
set(DDEFS "-DLPC43XX -DLPC43XX_M4 -D__NEWLIB__ -D${BOARD} -DTOOLCHAIN_GCC -DTOOLCHAIN_GCC_ARM -D_RANDOM_TCC=0 -D'VERSION_STRING=\"${VERSION}\"'")
# Upstream hackrf headers now gate on IS_* macros normally populated by
# hackrf/firmware/platform-detect.cmake. We don't include that here, so derive
# the IS_* set from BOARD ourselves. IS_H1_R9 is forced to 0 (compile-time
# constant) so `if (IS_H1_R9)` branches resolve without needing the runtime
# detected_platform() symbol, which mayhem doesn't link in.
if(BOARD STREQUAL "HACKRF_ONE")
set(BOARD_IS_DEFS "-DIS_HACKRF_ONE=1 -DIS_NOT_PRALINE=1 -DIS_H1_R9=0 -DIS_NOT_H1_R9=1 -DIS_NOT_RAD1O=1 -DIS_NOT_JAWBREAKER=1 -DIS_H1_OR_PRALINE=1 -DIS_H1_OR_RAD1O=1 -DIS_H1_OR_JAWBREAKER=1 -DIS_EXPANSION_COMPATIBLE=1")
elseif(BOARD STREQUAL "PRALINE")
set(BOARD_IS_DEFS "-DIS_PRALINE=1 -DIS_NOT_HACKRF_ONE=1 -DIS_NOT_H1_R9=1 -DIS_NOT_RAD1O=1 -DIS_NOT_JAWBREAKER=1 -DIS_H1_OR_PRALINE=1 -DIS_FOUR_LEDS=1 -DIS_EXPANSION_COMPATIBLE=1")
elseif(BOARD STREQUAL "RAD1O")
set(BOARD_IS_DEFS "-DIS_RAD1O=1 -DIS_NOT_PRALINE=1 -DIS_NOT_HACKRF_ONE=1 -DIS_NOT_H1_R9=1 -DIS_NOT_JAWBREAKER=1 -DIS_H1_OR_RAD1O=1 -DIS_FOUR_LEDS=1")
elseif(BOARD STREQUAL "JAWBREAKER")
set(BOARD_IS_DEFS "-DIS_JAWBREAKER=1 -DIS_NOT_PRALINE=1 -DIS_NOT_HACKRF_ONE=1 -DIS_NOT_H1_R9=1 -DIS_NOT_RAD1O=1 -DIS_H1_OR_JAWBREAKER=1")
else()
set(BOARD_IS_DEFS "")
endif()
set(DDEFS "-DLPC43XX -DLPC43XX_M4 -D__NEWLIB__ -D${BOARD} ${BOARD_IS_DEFS} -DTOOLCHAIN_GCC -DTOOLCHAIN_GCC_ARM -D_RANDOM_TCC=0 -D'VERSION_STRING=\"${VERSION}\"'")
# List all default ASM defines here, like -D_DEBUG=1
set(DADEFS)
@@ -765,7 +783,6 @@ set(MODE_CPPSRC
${HACKRF_PATH}/firmware/common/si5351c.c
${HACKRF_PATH}/firmware/common/i2c_bus.c
${HACKRF_PATH}/firmware/common/mixer.c
${HACKRF_PATH}/firmware/common/clkin.c
${HACKRF_PATH}/firmware/common/spi_bus.c
${HACKRF_PATH}/firmware/common/sgpio.c
${HACKRF_PATH}/firmware/common/rf_path.c
@@ -773,7 +790,6 @@ set(MODE_CPPSRC
${HACKRF_PATH}/firmware/common/spi_ssp.c
${HACKRF_PATH}/firmware/common/rffc5071_spi.c
${HACKRF_PATH}/firmware/common/rffc5071.c
${HACKRF_PATH}/firmware/common/clkin.c
${HACKRF_PATH}/firmware/common/gpdma.c
${HACKRF_PATH}/firmware/libopencm3/lib/cm3/nvic.c
+76 -77
View File
@@ -39,6 +39,7 @@
#include "platform_scu.h"
#include "fixed_point.h"
#include "clkin.h"
#include "usb_type.h"
#include <libopencm3/lpc43xx/cgu.h>
#include <libopencm3/lpc43xx/ccu.h>
#include <libopencm3/lpc43xx/scu.h>
@@ -147,34 +148,16 @@ static struct gpio gpio_h1r9_hw_sync_enable = GPIO(5, 5);
#endif
// clang-format on
i2c_bus_t i2c0 = {
.obj = (void*)I2C0_BASE,
.start = i2c_lpc_start,
.stop = i2c_lpc_stop,
.transfer = i2c_lpc_transfer,
};
i2c_bus_t i2c1 = {
.obj = (void*)I2C1_BASE,
.start = i2c_lpc_start,
.stop = i2c_lpc_stop,
.transfer = i2c_lpc_transfer,
};
// const i2c_lpc_config_t i2c_config_si5351c_slow_clock = {
// .duty_cycle_count = 15,
// };
const i2c_lpc_config_t i2c_config_si5351c_fast_clock = {
.duty_cycle_count = 255,
};
/* i2c0, i2c1, and i2c_config_si5351c_fast_clock are defined in
* hackrf/firmware/common/i2c_bus.c and si5351c.c; use those instead of
* redefining them here to avoid multiple-definition link errors. */
si5351c_driver_t clock_gen = {
.bus = &i2c0,
.i2c_address = 0x60,
};
const ssp_config_t ssp_config_max283x = {
ssp_config_t ssp_config_max283x = {
/* FIXME speed up once everything is working reliably */
/*
// Freq About 0.0498MHz / 49.8KHz => Freq = PCLK / (CPSDVSR * [SCR+1]) with PCLK=PLL1=204MHz
@@ -188,7 +171,7 @@ const ssp_config_t ssp_config_max283x = {
.gpio_select = &gpio_max283x_select,
};
const ssp_config_t ssp_config_max5864 = {
ssp_config_t ssp_config_max5864 = {
/* FIXME speed up once everything is working reliably */
/*
// Freq About 0.0498MHz / 49.8KHz => Freq = PCLK / (CPSDVSR * [SCR+1]) with PCLK=PLL1=204MHz
@@ -202,14 +185,8 @@ const ssp_config_t ssp_config_max5864 = {
.gpio_select = &gpio_max5864_select,
};
spi_bus_t spi_bus_ssp1 = {
.obj = (void*)SSP1_BASE,
.config = &ssp_config_max5864,
.start = spi_ssp_start,
.stop = spi_ssp_stop,
.transfer = spi_ssp_transfer,
.transfer_gather = spi_ssp_transfer_gather,
};
/* spi_bus_ssp1 is defined in hackrf/firmware/common/spi_bus.c. We update
* its .config at runtime in clock_init() to point at ssp_config_max5864. */
max283x_driver_t max283x = {};
@@ -224,14 +201,8 @@ ssp_config_t ssp_config_w25q80bv = {
.clock_prescale_rate = 2,
};
spi_bus_t spi_bus_ssp0 = {
.obj = (void*)SSP0_BASE,
.config = &ssp_config_w25q80bv,
.start = spi_ssp_start,
.stop = spi_ssp_stop,
.transfer = spi_ssp_transfer,
.transfer_gather = spi_ssp_transfer_gather,
};
/* spi_bus_ssp0 is defined in hackrf/firmware/common/spi_bus.c. We update
* its .config at runtime in clock_init() to point at ssp_config_w25q80bv. */
w25q80bv_driver_t spi_flash = {
.bus = &spi_bus_ssp0,
@@ -240,43 +211,8 @@ w25q80bv_driver_t spi_flash = {
.target_init = w25q80bv_target_init,
};
sgpio_config_t sgpio_config = {
.gpio_q_invert = &gpio_q_invert,
.gpio_trigger_enable = &gpio_hw_sync_enable,
.slice_mode_multislice = true,
};
rf_path_t rf_path = {
.switchctrl = 0,
#ifdef HACKRF_ONE
.gpio_hp = &gpio_hp,
.gpio_lp = &gpio_lp,
.gpio_tx_mix_bp = &gpio_tx_mix_bp,
.gpio_no_mix_bypass = &gpio_no_mix_bypass,
.gpio_rx_mix_bp = &gpio_rx_mix_bp,
.gpio_tx_amp = &gpio_tx_amp,
.gpio_tx = &gpio_tx,
.gpio_mix_bypass = &gpio_mix_bypass,
.gpio_rx = &gpio_rx,
.gpio_no_tx_amp_pwr = &gpio_no_tx_amp_pwr,
.gpio_amp_bypass = &gpio_amp_bypass,
.gpio_rx_amp = &gpio_rx_amp,
.gpio_no_rx_amp_pwr = &gpio_no_rx_amp_pwr,
#endif
#ifdef RAD1O
.gpio_tx_rx_n = &gpio_tx_rx_n,
.gpio_tx_rx = &gpio_tx_rx,
.gpio_by_mix = &gpio_by_mix,
.gpio_by_mix_n = &gpio_by_mix_n,
.gpio_by_amp = &gpio_by_amp,
.gpio_by_amp_n = &gpio_by_amp_n,
.gpio_mixer_en = &gpio_mixer_en,
.gpio_low_high_filt = &gpio_low_high_filt,
.gpio_low_high_filt_n = &gpio_low_high_filt_n,
.gpio_tx_amp = &gpio_tx_amp,
.gpio_rx_lna = &gpio_rx_lna,
#endif
};
/* sgpio_config and rf_path are defined in hackrf/firmware/common/sgpio.c and
* rf_path.c. Their gpio_* fields are populated at runtime in pin_setup(). */
jtag_gpio_t jtag_gpio_cpld = {
.gpio_tms = &gpio_cpld_tms,
@@ -681,7 +617,7 @@ void cpu_clock_init(void) {
si5351c_set_clock_source(&clock_gen, PLL_SOURCE_XTAL);
// soft reset
si5351c_reset_pll(&clock_gen);
si5351c_reset_pll(&clock_gen, SI5351C_PLL_BOTH);
si5351c_enable_clock_outputs(&clock_gen);
// FIXME disable I2C
@@ -866,6 +802,55 @@ void ssp1_set_mode_max5864(void) {
void pin_setup(void) {
const platform_scu_t* scu = platform_scu();
/* spi_bus_ssp0/1 are defined in hackrf/firmware/common/spi_bus.c with no
* .config. Patch in our SSP configs and SPI driver entry points here. */
spi_bus_ssp0.config = &ssp_config_w25q80bv;
spi_bus_ssp0.start = spi_ssp_start;
spi_bus_ssp0.stop = spi_ssp_stop;
spi_bus_ssp0.transfer = spi_ssp_transfer;
spi_bus_ssp0.transfer_gather = spi_ssp_transfer_gather;
spi_bus_ssp1.config = &ssp_config_max5864;
spi_bus_ssp1.start = spi_ssp_start;
spi_bus_ssp1.stop = spi_ssp_stop;
spi_bus_ssp1.transfer = spi_ssp_transfer;
spi_bus_ssp1.transfer_gather = spi_ssp_transfer_gather;
/* sgpio_config / rf_path are defined in common/sgpio.c and rf_path.c
* with minimal initializers. Populate the gpio_* fields here. */
sgpio_config.gpio_q_invert = &gpio_q_invert;
sgpio_config.gpio_trigger_enable = &gpio_hw_sync_enable;
sgpio_config.slice_mode_multislice = true;
#ifdef HACKRF_ONE
rf_path.gpio_hp = &gpio_hp;
rf_path.gpio_lp = &gpio_lp;
rf_path.gpio_tx_mix_bp = &gpio_tx_mix_bp;
rf_path.gpio_no_mix_bypass = &gpio_no_mix_bypass;
rf_path.gpio_rx_mix_bp = &gpio_rx_mix_bp;
rf_path.gpio_tx_amp = &gpio_tx_amp;
rf_path.gpio_tx = &gpio_tx;
rf_path.gpio_mix_bypass = &gpio_mix_bypass;
rf_path.gpio_rx = &gpio_rx;
rf_path.gpio_no_tx_amp_pwr = &gpio_no_tx_amp_pwr;
rf_path.gpio_amp_bypass = &gpio_amp_bypass;
rf_path.gpio_rx_amp = &gpio_rx_amp;
rf_path.gpio_no_rx_amp_pwr = &gpio_no_rx_amp_pwr;
#endif
#ifdef RAD1O
rf_path.gpio_tx_rx_n = &gpio_tx_rx_n;
rf_path.gpio_tx_rx = &gpio_tx_rx;
rf_path.gpio_by_mix = &gpio_by_mix;
rf_path.gpio_by_mix_n = &gpio_by_mix_n;
rf_path.gpio_by_amp = &gpio_by_amp;
rf_path.gpio_by_amp_n = &gpio_by_amp_n;
rf_path.gpio_mixer_en = &gpio_mixer_en;
rf_path.gpio_low_high_filt = &gpio_low_high_filt;
rf_path.gpio_low_high_filt_n = &gpio_low_high_filt_n;
rf_path.gpio_tx_amp = &gpio_tx_amp;
rf_path.gpio_rx_lna = &gpio_rx_lna;
#endif
/* Configure all GPIO as Input (safe state) */
// gpio_init();
@@ -1070,3 +1055,17 @@ void halt_and_flash(const uint32_t duration) {
delay(duration);
}
}
/* Upstream commit 85dfacf6 ("Universalize: firmware/hackrf_usb") wired
* usb_endpoint_control_out.setup_complete to transceiver_usb_setup_complete
* (defined in hackrf_usb/usb_api_transceiver.c). That function dispatches
* transceiver-specific SETUP packets and falls through to usb_setup_complete
* for everything else. sd_over_usb doesn't link the transceiver API, so
* provide a shim that always delegates to the standard handler. Without
* this, EP0 SETUP packets get a no-op completion and enumeration times out
* (host reports "device descriptor read/64, error -110"). */
void usb_setup_complete(usb_endpoint_t* const endpoint);
void transceiver_usb_setup_complete(usb_endpoint_t* const endpoint);
void transceiver_usb_setup_complete(usb_endpoint_t* const endpoint) {
usb_setup_complete(endpoint);
}
+28 -1
View File
@@ -22,6 +22,28 @@
#include "sd_over_usb.h"
#include "scsi.h"
#include "usb_descriptor.h"
#include <string.h>
/* Defined in hackrf/firmware/hackrf_usb/usb_device.c. After upstream commit
* 85dfacf6 ("Universalize: firmware/hackrf_usb"), the global `usb_device` is
* left zero-initialized and is populated at runtime from per-board
* `usb_device_*` constants inside hackrf_usb.c. The sd_over_usb baseband
* does not link hackrf_usb.c, so populate `usb_device` ourselves before
* usb_run(). The descriptor fields are const-qualified, so use the upstream
* memcpy-from-template pattern. */
extern usb_configuration_t* usb_configurations[];
static const usb_device_t usb_device_sd_over_usb = {
.descriptor = usb_descriptor_device,
.descriptor_strings = usb_descriptor_strings,
.qualifier_descriptor = usb_descriptor_device_qualifier,
.configurations = &usb_configurations,
.configuration = 0,
.wcid_string_descriptor = wcid_string_descriptor,
.wcid_feature_descriptor = wcid_feature_descriptor,
};
volatile bool scsi_running = false;
@@ -74,6 +96,8 @@ void start_usb(void) {
pin_setup();
cpu_clock_init();
memcpy(&usb_device, &usb_device_sd_over_usb, sizeof(usb_device_sd_over_usb));
usb_set_configuration_changed_cb(usb_configuration_changed);
usb_peripheral_reset();
@@ -85,7 +109,10 @@ void start_usb(void) {
usb_queue_init(&usb_endpoint_bulk_in_queue);
usb_endpoint_init(&usb_endpoint_control_out, false);
usb_endpoint_init(&usb_endpoint_control_in, false);
/* Match the new usb_endpoint_init() contract introduced upstream by
* db73ecbf, control IN needs ZLP for transfers whose length is a
* multiple of the EP0 max packet size, otherwise the host hangs. */
usb_endpoint_init(&usb_endpoint_control_in, true);
nvic_set_priority(NVIC_USB0_IRQ, 255);
+1 -1
Submodule hackrf updated: 442d95e23d...0bf478ed25