diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 21593d8a..02239f82 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -17,127 +17,70 @@ jobs: host: strategy: matrix: - os: ['macos', 'ubuntu', 'windows'] - cmake: ['3.10.0', '3.21.7', '4.2.6', 'latest'] - compiler: ['gcc', 'msvc'] + sys: + - {os: 'macos', shell: 'bash'} + - {os: 'ubuntu', shell: 'bash'} + - {os: 'windows', shell: 'pwsh'} + - {os: 'windows', shell: 'msys2'} + cmake: ['3.10.0', '3.16.0', '3.21.0', '4.0.0', 'latest'] exclude: - # MSVC only runs on Windows. - - os: 'macos' - compiler: 'msvc' - - os: 'ubuntu' - compiler: 'msvc' - # We can't use the oldest CMake versions on Windows. - - os: 'windows' + # GitHub runners use Visual Studio 2022. Support added in CMake 3.21. + - sys: {os: 'windows', shell: 'pwsh'} cmake: '3.10.0' - # The in-between CMake versions aren't so intersting with GCC. - - compiler: 'gcc' - cmake: '3.21.7' - - compiler: 'gcc' - cmake: '4.2.6' + - sys: {os: 'windows', shell: 'pwsh'} + cmake: '3.16.0' + # MSYS2 always supplies the latest cmake. + - sys: {os: 'windows', shell: 'msys2'} + cmake: '3.10.0' + - sys: {os: 'windows', shell: 'msys2'} + cmake: '3.16.0' + - sys: {os: 'windows', shell: 'msys2'} + cmake: '3.21.0' + - sys: {os: 'windows', shell: 'msys2'} + cmake: '4.0.0' include: - # Shell selection - - os: 'macos' - shell: 'bash' - - os: 'ubuntu' - shell: 'bash' - - os: 'windows' - compiler: 'msvc' - shell: 'pwsh' - - os: 'windows' - compiler: 'gcc' - shell: 'msys2' - # MSVC version selection - - cmake: '3.21.7' - msvc: '17.14' - - cmake: '4.2.6' - msvc: 'latest' - - cmake: 'latest' - msvc: 'latest' - # CMake generator selection - - os: 'macos' - generator: 'Unix Makefiles' - - os: 'ubuntu' - generator: 'Unix Makefiles' - - compiler: 'msvc' - cmake: '3.21.7' - generator: 'Visual Studio 17 2022' - - compiler: 'msvc' - cmake: '4.2.6' - generator: 'Visual Studio 18 2026' - - compiler: 'msvc' - cmake: 'latest' - generator: 'Visual Studio 18 2026' - - os: 'windows' - compiler: 'gcc' - generator: 'MSYS Makefiles' - # Additional CMake arguments - - os: 'windows' - compiler: 'msvc' + - sys: {os: 'windows', shell: 'pwsh'} cmake_args: >- -DPKG_CONFIG_EXECUTABLE=C:/vcpkg/installed/x64-windows/tools/pkgconf/pkgconf.exe -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake --install-prefix=$env:GITHUB_WORKSPACE/install - - os: 'windows' - compiler: 'gcc' + - sys: {os: 'windows', shell: 'msys2'} cmake_args: >- --install-prefix=/usr/local - # CMake 3.10 uses --build with --target install - - cmake: '3.10.0' - install_cmd: --build - install_args: --target install - # Later versions just use --install - - cmake: '3.21.7' - install_cmd: --install - - cmake: '4.2.6' - install_cmd: --install - - cmake: 'latest' - install_cmd: --install - # We need sudo on MacOS and Ubuntu only - - os: macos - sudo: sudo - - os: ubuntu - sudo: sudo - # Don't cancel all builds when one fails fail-fast: false - runs-on: ${{ matrix.os }}-latest + runs-on: ${{ matrix.sys.os }}-latest defaults: run: - shell: '${{ matrix.shell }} {0}' + shell: '${{ matrix.sys.shell }} {0}' steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v4 - name: Setup cmake uses: lukka/get-cmake@latest with: cmakeVersion: ${{ matrix.cmake }} - if: matrix.shell != 'msys2' - - - name: Install MSVC (Windows) - uses: k3DW/setup-msvc@v1 - with: - vs-version: ${{ matrix.msvc }} - if: matrix.compiler == 'msvc' && matrix.msvc != 'latest' + if: matrix.sys.shell != 'msys2' - name: Install dependencies (macOS) run: brew install fftw - if: matrix.os == 'macos' + if: matrix.sys.os == 'macos' - name: Install dependencies (Ubuntu) run: | sudo apt update sudo apt install libfftw3-dev libusb-1.0-0-dev - if: matrix.os == 'ubuntu' + if: matrix.sys.os == 'ubuntu' - name: Install dependencies (Windows) run: vcpkg install --triplet=x64-windows libusb fftw3 pthreads pkgconf - if: matrix.os == 'windows' && matrix.shell != 'msys2' + if: matrix.sys.os == 'windows' && matrix.sys.shell != 'msys2' - name: Setup MSYS (Windows) - if: matrix.os == 'windows' && matrix.shell == 'msys2' + if: matrix.sys.os == 'windows' && matrix.sys.shell == 'msys2' uses: msys2/setup-msys2@v2 with: msystem: UCRT64 @@ -155,7 +98,7 @@ jobs: run: | cmake -E make_directory host/build cd host/build - cmake .. -G "${{ matrix.generator }}" -DCMAKE_BUILD_TYPE=Release ${{matrix.cmake_args}} + cmake .. -DCMAKE_BUILD_TYPE=Release ${{matrix.cmake_args}} cmake --build . --config Release # Build libhackrf ONLY @@ -164,12 +107,22 @@ jobs: run: | cmake -E make_directory host/libhackrf/build cd host/libhackrf/build - cmake .. -G "${{ matrix.generator }}" -DCMAKE_BUILD_TYPE=Release ${{ matrix.cmake_args }} + cmake .. -DCMAKE_BUILD_TYPE=Release ${{ matrix.cmake_args }} cmake --build . --config Release - name: Install (libhackrf) run: | - ${{ matrix.sudo }} cmake ${{ matrix.install_cmd }} host/libhackrf/build ${{ matrix.install_args }} --config Release + sudo cmake --install host/libhackrf/build --config Release + if: matrix.sys.os != 'windows' && matrix.cmake != '3.10.0' + + - name: Install (libhackrf, CMake 3.10) + run: | + sudo cmake --build host/libhackrf/build --target install --config Release + if: matrix.sys.os != 'windows' && matrix.cmake == '3.10.0' + + - name: Install (libhackrf, Windows) + run: cmake --install host/libhackrf/build --config Release + if: matrix.sys.os == 'windows' # Build hackrf-tools ONLY @@ -177,12 +130,22 @@ jobs: run: | cmake -E make_directory host/hackrf-tools/build cd host/hackrf-tools/build - cmake .. -G "${{ matrix.generator }}" -DCMAKE_BUILD_TYPE=Release ${{ matrix.cmake_args }} + cmake .. -DCMAKE_BUILD_TYPE=Release ${{ matrix.cmake_args }} cmake --build . --config Release - name: Install (hackrf-tools) run: | - ${{ matrix.sudo }} cmake ${{ matrix.install_cmd }} host/hackrf-tools/build ${{ matrix.install_args }} + sudo cmake --install host/hackrf-tools/build --config Release + if: matrix.sys.os != 'windows' && matrix.cmake != '3.10.0' + + - name: Install (hackrf-tools, CMake 3.10) + run: | + sudo cmake --build host/hackrf-tools/build --target install --config Release + if: matrix.sys.os != 'windows' && matrix.cmake == '3.10.0' + + - name: Install (hackrf-tools, Windows) + run: cmake --install host/hackrf-tools/build --config Release + if: matrix.sys.os == 'windows' # Publish the contents of install/bin (which should be the combination libhackrf and host-tools) for Windows - name: Publish Artifacts (Windows) @@ -190,7 +153,7 @@ jobs: with: name: hackrf-tools-windows path: ${{github.workspace}}/install/bin - if: matrix.os == 'windows' && matrix.cmake == 'latest' && matrix.shell == 'pwsh' + if: matrix.sys.os == 'windows' && matrix.cmake == 'latest' && matrix.sys.shell == 'pwsh' firmware: strategy: @@ -216,7 +179,7 @@ jobs: runs-on: ${{ matrix.os }}-latest steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v4 with: submodules: true diff --git a/.github/workflows/clang-format-check.yml b/.github/workflows/clang-format-check.yml index d498d609..0bf33429 100644 --- a/.github/workflows/clang-format-check.yml +++ b/.github/workflows/clang-format-check.yml @@ -16,7 +16,7 @@ jobs: - check: 'firmware/hackrf_usb' exclude: '' steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v4 - name: Run clang-format-action uses: jidicula/clang-format-action@v4.6.2 with: diff --git a/Jenkinsfile b/Jenkinsfile index dcfd9ad8..b41d6714 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -39,15 +39,31 @@ pipeline { timeout(time: 20, unit: 'MINUTES') } steps { - runCommand("Install Host Tools", './ci-scripts/install_host.sh', 3, 1, 'MINUTES') - runCommand("Build HackRF One Firmware", './ci-scripts/build_firmware.sh HACKRF_ONE', 3, 1, 'MINUTES') - lock('HIL_hubs') { - script { - allOff() - runTest("Check Host", 'h1_eut', './ci-scripts/test_host.sh') - runTest("HackRF One HIL Test", 'h1_tester h1_eut', h1_test) - runTest("SGPIO Debug Test", 'h1_eut', 'python3 ci-scripts/test_sgpio_debug.py') - } + sh './ci-scripts/install_host.sh' + sh './ci-scripts/build_firmware.sh HACKRF_ONE' + script { + allOff() + reset('h1_eut') + } + sh 'sleep 1s' + retry(3) { + sh './ci-scripts/test_host.sh' + } + script { + reset('h1_tester h1_eut') + } + sh 'sleep 1s' + script { + // Allow up to 3 retries 5 minutes each for the HIL test + runCommand(3, 5, 'MINUTES', "HackRF One Test", h1_test) + } + script { + allOff() + reset('h1_eut') + } + sh 'sleep 1s' + retry(3) { + sh 'python3 ci-scripts/test_sgpio_debug.py' } } } @@ -63,17 +79,32 @@ pipeline { timeout(time: 20, unit: 'MINUTES') } steps { - runCommand("Install Host Tools", './ci-scripts/install_host.sh', 3, 1, 'MINUTES') - runCommand("Build Universal Firmware", './ci-scripts/build_firmware.sh UNIVERSAL', 3, 1, 'MINUTES') - lock('HIL_hubs') { - script { - allOff() - runTest("Check Host", 'h1_eut', './ci-scripts/test_host.sh') - runTest("HackRF One HIL Test", 'h1_tester h1_eut', h1_test) - runTest("SGPIO Debug Test", 'h1_eut', 'python3 ci-scripts/test_sgpio_debug.py') - } + sh './ci-scripts/install_host.sh' + sh './ci-scripts/build_firmware.sh UNIVERSAL' + script { + allOff() + reset('h1_eut') + } + sh 'sleep 1s' + retry(3) { + sh './ci-scripts/test_host.sh' + } + script { + reset('h1_tester h1_eut') + } + sh 'sleep 1s' + script { + // Allow up to 3 retries 5 minutes each for the HIL test + runCommand(3, 5, 'MINUTES', "HackRF One Test", h1_test) + } + script { + allOff() + reset('h1_eut') + } + sh 'sleep 1s' + retry(3) { + sh 'python3 ci-scripts/test_sgpio_debug.py' } - } } stage('Test HackRF Pro with BOARD=PRALINE') { @@ -88,14 +119,23 @@ pipeline { timeout(time: 20, unit: 'MINUTES') } steps { - runCommand("Install Host Tools", './ci-scripts/install_host.sh', 3, 1, 'MINUTES') - runCommand("Build Praline Firmware", './ci-scripts/build_firmware.sh PRALINE', 3, 1, 'MINUTES') - lock('HIL_hubs') { - script { - allOff() - runTest("Check Host", 'hpro_eut', './ci-scripts/test_host.sh') - runTest("HackRF Pro HIL Test", 'hpro_tester hpro_eut', hpro_test) - } + sh './ci-scripts/install_host.sh' + sh './ci-scripts/build_firmware.sh PRALINE' + script { + allOff() + reset('hpro_eut') + } + sh 'sleep 1s' + retry(3) { + sh './ci-scripts/test_host.sh' + } + script { + reset('hpro_tester hpro_eut') + } + sh 'sleep 1s' + script { + // Allow up to 3 retries 5 minutes each for the HIL test + runCommand(3, 5, 'MINUTES', "HackRF Pro Test", hpro_test) } } } @@ -111,14 +151,23 @@ pipeline { timeout(time: 20, unit: 'MINUTES') } steps { - runCommand("Install Host Tools", './ci-scripts/install_host.sh', 3, 1, 'MINUTES') - runCommand("Build Universal Firmware", './ci-scripts/build_firmware.sh UNIVERSAL', 3, 1, 'MINUTES') - lock('HIL_hubs') { - script { - allOff() - runTest("Check Host", 'hpro_eut', './ci-scripts/test_host.sh') - runTest("HackRF Pro HIL Test", 'hpro_tester hpro_eut', hpro_test) - } + sh './ci-scripts/install_host.sh' + sh './ci-scripts/build_firmware.sh UNIVERSAL' + script { + allOff() + reset('hpro_eut') + } + sh 'sleep 1s' + retry(3) { + sh './ci-scripts/test_host.sh' + } + script { + reset('hpro_tester hpro_eut') + } + sh 'sleep 1s' + script { + // Allow up to 3 retries 5 minutes each for the HIL test + runCommand(3, 5, 'MINUTES', "HackRF Pro Test", hpro_test) } } } @@ -135,15 +184,15 @@ pipeline { def allOff() { // Allow up to 3 retries, 20 seconds each, for the USB hub port power server to respond appropriately - runCommand('USB hub port power server command', "hubs all off", 3, 20, 'SECONDS') + runCommand(3, 20, 'SECONDS', 'USB hub port power server command', "hubs all off") } def reset(devices) { // Allow up to 3 retries, 20 seconds each, for the USB hub port power server to respond appropriately - runCommand('USB hub port power server command', "hubs ${devices} reset", 3, 20, 'SECONDS') + runCommand(3, 20, 'SECONDS', 'USB hub port power server command', "hubs ${devices} reset") } -def runCommand(title, cmd, retries, time, unit) { +def runCommand(retries, time, unit, title, cmd) { retry(retries) { try { timeout(time: time, unit: unit) { @@ -165,13 +214,3 @@ def runCommand(title, cmd, retries, time, unit) { } } } - -def runTest(title, devices, cmd) { - retry(3) { - // reset() retains it's own internal retries - reset(devices) - sh 'sleep 1s' - // run the test with 0 internal retries and 3 external retries to ensure resets between runs - runCommand(title, cmd, 0, 5, 'MINUTES') - } -} diff --git a/firmware/common/clock_gen.c b/firmware/common/clock_gen.c index a709960b..0cf21ab2 100644 --- a/firmware/common/clock_gen.c +++ b/firmware/common/clock_gen.c @@ -24,6 +24,8 @@ #include #include "hackrf_ui.h" +#include "i2c_bus.h" +#include "i2c_lpc.h" #include "platform_detect.h" #include "sgpio.h" #include "si5351c.h" @@ -34,6 +36,8 @@ void clock_gen_init(void) { + i2c_bus_start(si5351c.bus, &i2c_config_fast_clock); + si5351c_init(&si5351c); si5351c_disable_all_outputs(&si5351c); si5351c_disable_oeb_pin_control(&si5351c); @@ -116,6 +120,7 @@ void clock_gen_init(void) void clock_gen_shutdown(void) { + i2c_bus_start(si5351c.bus, &i2c_config_fast_clock); si5351c_disable_all_outputs(&si5351c); si5351c_disable_oeb_pin_control(&si5351c); si5351c_power_down_all_clocks(&si5351c); diff --git a/firmware/common/fixed_point.h b/firmware/common/fixed_point.h index 974e34d2..b6908797 100644 --- a/firmware/common/fixed_point.h +++ b/firmware/common/fixed_point.h @@ -54,20 +54,3 @@ typedef uint64_t fp_28_36_t; #define SR_FP_MHZ(mhz) (mhz##ULL * SR_FP_ONE_MHZ) #define SR_FP_KHZ(khz) (khz##ULL * SR_FP_ONE_KHZ) #define SR_FP_HZ(hz) (hz##ULL * SR_FP_ONE_HZ) - -/* 1.63 fixed point */ -typedef uint64_t fp_1_63_t; - -#define FRAC_ONE (1ULL << 63) - -/* one hundredth in 1.63 fixed point */ -#define FRAC_ONE_PERCENT (FRAC_ONE / (100ULL)) - -/* one thousandth in 1.63 fixed point */ -#define FRAC_ONE_PERMILLE (FRAC_ONE / (1000ULL)) - -/* one millionth in 1.63 fixed point */ -#define FRAC_ONE_PPM (FRAC_ONE / (1000000ULL)) - -/* one billionth in 1.63 fixed point */ -#define FRAC_ONE_PPB (FRAC_ONE / (1000000000ULL)) diff --git a/firmware/common/i2c_lpc.c b/firmware/common/i2c_lpc.c index 2c0fc5e2..9d6499fa 100644 --- a/firmware/common/i2c_lpc.c +++ b/firmware/common/i2c_lpc.c @@ -25,8 +25,6 @@ #include #include -#include "cpu_clock.h" - /* Driver instances. */ i2c_bus_t i2c0 = { .obj = (void*) I2C0_BASE, @@ -43,7 +41,7 @@ i2c_bus_t i2c1 = { }; const i2c_lpc_config_t i2c_config_fast_clock = { - .clock_khz = 400, + .duty_cycle_count = 255, }; /* FIXME return i2c0 status from each function */ @@ -53,9 +51,7 @@ void i2c_lpc_start(i2c_bus_t* const bus, const void* const _config) const i2c_lpc_config_t* const config = _config; const uint32_t port = (uint32_t) bus->obj; - const uint16_t duty_cycle_count = - (cpu_clock_mhz * (2000 / config->clock_khz)) / 4; - i2c_init(port, duty_cycle_count); + i2c_init(port, config->duty_cycle_count); } void i2c_lpc_stop(i2c_bus_t* const bus) diff --git a/firmware/common/i2c_lpc.h b/firmware/common/i2c_lpc.h index 2a2562ee..e71cb362 100644 --- a/firmware/common/i2c_lpc.h +++ b/firmware/common/i2c_lpc.h @@ -29,7 +29,7 @@ #include "i2c_bus.h" typedef struct { - const uint16_t clock_khz; + const uint16_t duty_cycle_count; } i2c_lpc_config_t; void i2c_lpc_start(i2c_bus_t* const bus, const void* const config); diff --git a/firmware/common/radio.c b/firmware/common/radio.c index 36f65cad..f8b2e514 100644 --- a/firmware/common/radio.c +++ b/firmware/common/radio.c @@ -34,7 +34,6 @@ #include "rf_path.h" #include "transceiver_mode.h" #include "tuning.h" -#include "u128.h" #ifdef IS_PRALINE #include "fpga.h" #include "tune_config.h" @@ -54,7 +53,7 @@ void radio_init(radio_t* const radio) } } radio->config[RADIO_BANK_APPLIED][RADIO_OPMODE] = TRANSCEIVER_MODE_OFF; - radio->config[RADIO_BANK_REQUESTED][RADIO_OPMODE] = TRANSCEIVER_MODE_OFF; + radio->config[RADIO_BANK_ACTIVE][RADIO_OPMODE] = TRANSCEIVER_MODE_OFF; radio->config[RADIO_BANK_IDLE][RADIO_OPMODE] = TRANSCEIVER_MODE_OFF; radio->config[RADIO_BANK_RX][RADIO_OPMODE] = TRANSCEIVER_MODE_RX; radio->config[RADIO_BANK_TX][RADIO_OPMODE] = TRANSCEIVER_MODE_TX; @@ -78,7 +77,7 @@ radio_error_t radio_reg_write( } switch (bank) { - case RADIO_BANK_REQUESTED: + case RADIO_BANK_ACTIVE: mark_dirty(radio, reg); /* fall through */ case RADIO_BANK_IDLE: @@ -133,75 +132,6 @@ static uint32_t radio_update_direction(radio_t* const radio, uint64_t* bank) return (1 << RADIO_OPMODE); } -/* Apply correction to a true frequency to get an adjusted frequency. */ -static uint64_t adjust(uint64_t freq, uint64_t correction) -{ - /* skip if we can */ - if (correction == FRAC_ONE) { - return freq; - } - - u128 product = u128_multiply(freq, correction); - - /* product >> 63 */ - return (product.hi << 1) | (product.lo >> 63); -} - -/* Given an adjusted frequency and correction, return the true frequency. */ -static uint64_t unadjust(uint64_t freq, uint64_t correction) -{ - /* skip if we can */ - if (correction == FRAC_ONE) { - return freq; - } - - /* (1 << (63 + 63)) */ - u128 numerator = (u128){ - .hi = 1ULL << 62, - .lo = 0, - }; - u128 denominator = (u128){ - .hi = 0, - .lo = correction, - }; - u128 reciprocal = u128_divide(numerator, denominator); - return adjust(freq, reciprocal.lo); -} - -static uint64_t restrict_correction(uint64_t requested_correction) -{ - /* Correction should be in the range 0.99 to 1.01 */ - const uint64_t min_correction = FRAC_ONE - FRAC_ONE_PERCENT; - const uint64_t max_correction = FRAC_ONE + FRAC_ONE_PERCENT; - if (requested_correction >= min_correction && - requested_correction <= max_correction) { - return requested_correction; - } else { - return FRAC_ONE; - } -} - -static uint64_t set_lo(uint64_t freq_lo, uint64_t correction, bool apply) -{ - fp_40_24_t corrected_lo = adjust(freq_lo, correction); - fp_40_24_t achieved_lo = mixer_set_frequency(&mixer, corrected_lo, apply); - return unadjust(achieved_lo, correction); -} - -static uint64_t set_if(uint64_t freq_if, uint64_t correction, bool apply) -{ - fp_40_24_t corrected_if = adjust(freq_if, correction); - fp_40_24_t achieved_if = max283x_set_frequency(&max283x, corrected_if, apply); - return unadjust(achieved_if, correction); -} - -static uint64_t set_afe_rate(uint64_t afe_rate, uint64_t correction, bool apply) -{ - fp_28_36_t corrected_rate = adjust(afe_rate, correction); - fp_28_36_t achieved_rate = sample_rate_set(corrected_rate, apply); - return unadjust(achieved_rate, correction); -} - #define ABSOLUTE_MIN_AFE_RATE SR_FP_KHZ(200) #define ABSOLUTE_MAX_AFE_RATE SR_FP_KHZ(43600) #define MAX_SUPPORTED_AFE_RATE SR_FP_KHZ(40000) @@ -253,9 +183,6 @@ static uint32_t radio_update_sample_rate(radio_t* const radio, uint64_t* bank) bool new_n = false; const uint64_t requested_rate = bank[RADIO_SAMPLE_RATE]; - const uint64_t requested_correction = bank[RADIO_CLOCK_CORRECTION]; - - uint64_t correction = restrict_correction(requested_correction); if (requested_rate != RADIO_UNSET) { rate = MIN(requested_rate, MAX_MCU_RATE); @@ -309,7 +236,7 @@ static uint32_t radio_update_sample_rate(radio_t* const radio, uint64_t* bank) new_n = (n != previous_n); afe_rate = rate << n; - afe_rate = set_afe_rate(afe_rate, correction, false); + afe_rate = sample_rate_set(afe_rate, false); previous_rate = radio->config[RADIO_BANK_APPLIED][RADIO_SAMPLE_RATE]; if ((previous_n == RADIO_UNSET) || previous_rate == RADIO_UNSET) { previous_afe_rate = RADIO_UNSET; @@ -318,7 +245,7 @@ static uint32_t radio_update_sample_rate(radio_t* const radio, uint64_t* bank) } new_afe_rate = (afe_rate != previous_afe_rate); if (new_afe_rate) { - afe_rate = set_afe_rate(afe_rate, correction, true); + afe_rate = sample_rate_set(afe_rate, true); } rate = afe_rate >> n; @@ -446,7 +373,6 @@ static uint32_t radio_update_frequency(radio_t* const radio, uint64_t* bank) #ifdef IS_PRALINE const uint64_t requested_rotation = bank[RADIO_ROTATION]; #endif - const uint64_t requested_correction = bank[RADIO_CLOCK_CORRECTION]; const uint64_t applied_rf = radio->config[RADIO_BANK_APPLIED][RADIO_FREQUENCY_RF]; const uint64_t applied_if = radio->config[RADIO_BANK_APPLIED][RADIO_FREQUENCY_IF]; @@ -455,8 +381,6 @@ static uint32_t radio_update_frequency(radio_t* const radio, uint64_t* bank) radio->config[RADIO_BANK_APPLIED][RADIO_IMAGE_REJECT]; const uint64_t applied_rotation = radio->config[RADIO_BANK_APPLIED][RADIO_ROTATION]; - const uint64_t applied_correction = - radio->config[RADIO_BANK_APPLIED][RADIO_CLOCK_CORRECTION]; uint64_t freq_rf = applied_rf; uint64_t analog_rf = applied_rf; @@ -464,7 +388,6 @@ static uint32_t radio_update_frequency(radio_t* const radio, uint64_t* bank) uint64_t freq_lo = applied_lo; uint64_t img_reject = applied_img_reject; uint64_t rotation = applied_rotation; - uint64_t correction = applied_correction; uint64_t opmode = bank[RADIO_OPMODE]; if (opmode == RADIO_UNSET) { @@ -482,12 +405,11 @@ static uint32_t radio_update_frequency(radio_t* const radio, uint64_t* bank) img_reject = RF_PATH_FILTER_BYPASS; } } - correction = restrict_correction(requested_correction); if (requested_if != RADIO_UNSET) { - freq_if = set_if(requested_if, correction, false); + freq_if = max283x_set_frequency(&max283x, requested_if, false); } if (requested_lo != RADIO_UNSET) { - freq_lo = set_lo(requested_lo, correction, false); + freq_lo = mixer_set_frequency(&mixer, freq_lo, false); } #ifdef IS_PRALINE if (IS_PRALINE) { @@ -569,7 +491,7 @@ static uint32_t radio_update_frequency(radio_t* const radio, uint64_t* bank) freq_lo = RADIO_UNSET; } if (freq_lo != RADIO_UNSET) { - freq_lo = set_lo(freq_lo, correction, false); + freq_lo = mixer_set_frequency(&mixer, freq_lo, false); } } @@ -591,12 +513,12 @@ static uint32_t radio_update_frequency(radio_t* const radio, uint64_t* bank) /* Apply settings. */ if ((freq_if != applied_if) && (freq_if != RADIO_UNSET)) { - freq_if = set_if(freq_if, correction, true); + freq_if = max283x_set_frequency(&max283x, freq_if, true); radio->config[RADIO_BANK_APPLIED][RADIO_FREQUENCY_IF] = freq_if; changed |= (1 << RADIO_FREQUENCY_IF); } if ((freq_lo != applied_lo) && (freq_lo != RADIO_UNSET)) { - freq_lo = set_lo(freq_lo, correction, true); + freq_lo = mixer_set_frequency(&mixer, freq_lo, true); radio->config[RADIO_BANK_APPLIED][RADIO_FREQUENCY_LO] = freq_lo; changed |= (1 << RADIO_FREQUENCY_LO); } @@ -639,10 +561,6 @@ static uint32_t radio_update_frequency(radio_t* const radio, uint64_t* bank) radio->config[RADIO_BANK_APPLIED][RADIO_FREQUENCY_RF] = freq_rf; changed |= (1 << RADIO_FREQUENCY_RF); } - if ((correction != applied_correction) && (correction != RADIO_UNSET)) { - radio->config[RADIO_BANK_APPLIED][RADIO_CLOCK_CORRECTION] = correction; - changed |= (1 << RADIO_CLOCK_CORRECTION); - } return changed; } @@ -937,7 +855,7 @@ bool radio_update(radio_t* const radio) return false; } radio->regs_dirty = 0; - memcpy(&tmp_bank[0], &(radio->config[RADIO_BANK_REQUESTED][0]), sizeof(tmp_bank)); + memcpy(&tmp_bank[0], &(radio->config[RADIO_BANK_ACTIVE][0]), sizeof(tmp_bank)); nvic_enable_irq(NVIC_USB0_IRQ); if ((dirty & RADIO_REG_GROUP_RATE) || @@ -998,14 +916,14 @@ void radio_switch_opmode(radio_t* const radio, const transceiver_mode_t mode) nvic_disable_irq(NVIC_USB0_IRQ); for (uint8_t reg = 0; reg < RADIO_NUM_REGS; reg++) { value = radio->config[source_bank][reg]; - previous = radio->config[RADIO_BANK_REQUESTED][reg]; + previous = radio->config[RADIO_BANK_ACTIVE][reg]; if ((value != RADIO_UNSET) && (value != previous)) { - radio->config[RADIO_BANK_REQUESTED][reg] = value; + radio->config[RADIO_BANK_ACTIVE][reg] = value; mark_dirty(radio, reg); } } - radio->config[RADIO_BANK_REQUESTED][RADIO_OPMODE] = mode; + radio->config[RADIO_BANK_ACTIVE][RADIO_OPMODE] = mode; mark_dirty(radio, RADIO_OPMODE); nvic_enable_irq(NVIC_USB0_IRQ); radio_update(radio); diff --git a/firmware/common/radio.h b/firmware/common/radio.h index 8e12471a..821c7fea 100644 --- a/firmware/common/radio.h +++ b/firmware/common/radio.h @@ -165,23 +165,17 @@ typedef enum { * DC block enable of type bool. */ RADIO_DC_BLOCK = 22, - /** - * Correction factor for radio reference clock, of type fp_1_63_t. - */ - RADIO_CLOCK_CORRECTION = 23, } radio_register_t; -#define RADIO_NUM_REGS (24) +#define RADIO_NUM_REGS (23) #define RADIO_UNSET (0xffffffffffffffff) /* register groups for bitfield convenience */ -#define RADIO_REG_GROUP_RATE \ - ((1 << RADIO_SAMPLE_RATE) | (1 << RADIO_RESAMPLE_TX) | \ - (1 << RADIO_RESAMPLE_RX) | (1 << RADIO_CLOCK_CORRECTION)) -#define RADIO_REG_GROUP_FREQ \ - ((1 << RADIO_FREQUENCY_RF) | (1 << RADIO_FREQUENCY_IF) | \ - (1 << RADIO_FREQUENCY_LO) | (1 << RADIO_IMAGE_REJECT) | (1 << RADIO_ROTATION) | \ - (1 << RADIO_CLOCK_CORRECTION)) +#define RADIO_REG_GROUP_RATE \ + ((1 << RADIO_SAMPLE_RATE) | (1 << RADIO_RESAMPLE_TX) | (1 << RADIO_RESAMPLE_RX)) +#define RADIO_REG_GROUP_FREQ \ + ((1 << RADIO_FREQUENCY_RF) | (1 << RADIO_FREQUENCY_IF) | \ + (1 << RADIO_FREQUENCY_LO) | (1 << RADIO_IMAGE_REJECT) | (1 << RADIO_ROTATION)) #define RADIO_REG_GROUP_BW \ ((1 << RADIO_BB_BANDWIDTH_TX) | (1 << RADIO_BB_BANDWIDTH_RX) | \ (1 << RADIO_XCVR_TX_LPF) | (1 << RADIO_XCVR_RX_LPF) | \ @@ -191,7 +185,7 @@ typedef enum { (1 << RADIO_GAIN_RX_IF) | (1 << RADIO_GAIN_RX_BB)) /** - * Register bank RADIO_BANK_REQUESTED stores the active configuration. Active + * Register bank RADIO_BANK_ACTIVE stores the active configuration. Active * register settings are copied to the applied register when applied. * * The other three banks store settings that will be applied when switching to @@ -202,7 +196,7 @@ typedef enum { */ typedef enum { RADIO_BANK_APPLIED = 0, - RADIO_BANK_REQUESTED = 1, + RADIO_BANK_ACTIVE = 1, RADIO_BANK_IDLE = 2, RADIO_BANK_RX = 3, RADIO_BANK_TX = 4, @@ -237,7 +231,7 @@ typedef struct { void radio_init(radio_t* const radio); /** - * Write to one or more registers. Writes to RADIO_BANK_REQUESTED are applied at + * Write to one or more registers. Writes to RADIO_BANK_ACTIVE are applied at * the next radio_update(). Writes to RADIO_BANK_APPLIED are not supported. */ radio_error_t radio_reg_write( @@ -255,7 +249,7 @@ uint64_t radio_reg_read( const radio_register_t reg); /** - * Apply changes requested in RADIO_BANK_REQUESTED. + * Apply changes requested in RADIO_BANK_ACTIVE. * Return true if any changes were applied. */ bool radio_update(radio_t* const radio); diff --git a/firmware/common/si5351c.c b/firmware/common/si5351c.c index a455a23e..259c062a 100644 --- a/firmware/common/si5351c.c +++ b/firmware/common/si5351c.c @@ -274,6 +274,17 @@ void si5351c_enable_clock_outputs(si5351c_driver_t* const drv) SI5351C_OUTPUT_DISABLE); } si5351c_regs_commit(drv); + +#ifdef IS_H1_R9 + if (IS_H1_R9) { + const platform_gpio_t* gpio = platform_gpio(); + if (drv->clk[drv->clkout_id].output_enable) { + gpio_set(gpio->h1r9_clkout_en); + } else { + gpio_clear(gpio->h1r9_clkout_en); + } + } +#endif } void si5351c_set_int_mode( @@ -328,7 +339,7 @@ bool si5351c_clkin_signal_valid(si5351c_driver_t* const drv) } } -static void si5351c_clkout_ms_enable(si5351c_driver_t* const drv, bool enable) +void si5351c_clkout_enable(si5351c_driver_t* const drv, bool enable) { drv->clk[drv->clkout_id].output_enable = enable; drv->clk[drv->clkout_id].power_down = !enable; @@ -340,42 +351,12 @@ static void si5351c_clkout_ms_enable(si5351c_driver_t* const drv, bool enable) si5351c_enable_clock_outputs(drv); } -void si5351c_clkout_enable(si5351c_driver_t* const drv, bool enable) -{ -#ifdef IS_H1_R9 - if (IS_H1_R9) { - const platform_gpio_t* gpio = platform_gpio(); - - /* CLKOUT is shared with MCU_CLK, enable MS when either on. */ - bool mcu_clkin_enabled = gpio_read(gpio->h1r9_mcu_clk_en); - bool ms_needed = enable | mcu_clkin_enabled; - si5351c_clkout_ms_enable(drv, ms_needed); - - /* Set GPIO to gate CLKOUT output downstream of MS. */ - gpio_write(gpio->h1r9_clkout_en, enable); - } -#endif -#ifdef IS_NOT_H1_R9 - if (IS_NOT_H1_R9) { - /* We have a dedicated CLKOUT multisynth. */ - si5351c_clkout_ms_enable(drv, enable); - } -#endif -} - void si5351c_mcu_clkin_enable(si5351c_driver_t* const drv, bool enable) { #ifdef IS_H1_R9 if (IS_H1_R9) { - const platform_gpio_t* gpio = platform_gpio(); - - /* MCU_CLK is shared with CLKOUT, enable MS when either on. */ - bool clkout_enabled = gpio_read(gpio->h1r9_clkout_en); - bool ms_needed = enable | clkout_enabled; - si5351c_clkout_ms_enable(drv, ms_needed); - - /* Set GPIO to gate MCU_CLK output downstream of MS. */ - gpio_write(gpio->h1r9_mcu_clk_en, enable); + /* MCU clock is shared with CLKOUT. */ + si5351c_clkout_enable(drv, enable); } #endif #ifdef IS_NOT_H1_R9 diff --git a/firmware/common/u128.c b/firmware/common/u128.c deleted file mode 100644 index 3543f332..00000000 --- a/firmware/common/u128.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2026 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 "u128.h" - -/* From https://stackoverflow.com/a/58381061 */ - -u128 u128_multiply(uint64_t lhs, uint64_t rhs) -{ - uint64_t lo_lo = (lhs & 0xFFFFFFFF) * (rhs & 0xFFFFFFFF); - uint64_t hi_lo = (lhs >> 32) * (rhs & 0xFFFFFFFF); - uint64_t lo_hi = (lhs & 0xFFFFFFFF) * (rhs >> 32); - uint64_t hi_hi = (lhs >> 32) * (rhs >> 32); - uint64_t cross = ((lo_lo >> 32) + (hi_lo & 0xFFFFFFFF) + lo_hi); - return (u128){ - .hi = ((hi_lo >> 32) + (cross >> 32) + hi_hi), - .lo = ((cross << 32) | (lo_lo & 0xFFFFFFFF)), - }; -} - -/* From https://stackoverflow.com/a/70052545 */ - -/* clang-format off */ - -#define SUBCcc(a,b,cy,t0,t1,t2) \ - (t0=(b)+cy, t1=(a), cy=t0= divisor - rem.lo = tmp.lo; - rem.hi = tmp.hi; - quot.lo |= 1; - } - } - - return quot; -} diff --git a/firmware/common/u128.h b/firmware/common/u128.h deleted file mode 100644 index c51dc5f5..00000000 --- a/firmware/common/u128.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2026 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. - */ - -#pragma once - -#include - -typedef struct { - uint64_t hi; - uint64_t lo; -} u128; - -u128 u128_multiply(uint64_t a, uint64_t b); -u128 u128_divide(u128 dvnd, u128 dvsr); diff --git a/firmware/fpga/build/praline_fpga.bin b/firmware/fpga/build/praline_fpga.bin index 64dd9b4b..a6b02485 100644 Binary files a/firmware/fpga/build/praline_fpga.bin and b/firmware/fpga/build/praline_fpga.bin differ diff --git a/firmware/fpga/dsp/cic.py b/firmware/fpga/dsp/cic.py index 99f5376a..fa0f3fa0 100644 --- a/firmware/fpga/dsp/cic.py +++ b/firmware/fpga/dsp/cic.py @@ -240,7 +240,6 @@ class ProgrammableShift(wiring.Component): # Implement the map itself (should it be done outside?) max_shift = max(self.shift_map.values()) - min_shift = min(self.shift_map.values()) value_scaled = [ Signal(signed(self.width_in + max_shift)) for _ in range(self.num_channels) ] scaled_valid = Signal() @@ -256,9 +255,7 @@ class ProgrammableShift(wiring.Component): for k, v in self.shift_map.items(): with m.Case(k): m.d.sync += value_scaled[c].eq(self.input.payload[c] << (max_shift - v)) - with m.Default(): - m.d.sync += value_scaled[c].eq(self.input.payload[c] << (max_shift - min_shift)) - + with m.If(~self.output.valid | self.output.ready): m.d.comb += scaled_ready.eq(1) m.d.sync += self.output.valid.eq(scaled_valid) diff --git a/firmware/hackrf-common.cmake b/firmware/hackrf-common.cmake index 8f6698da..dfc67d9e 100644 --- a/firmware/hackrf-common.cmake +++ b/firmware/hackrf-common.cmake @@ -203,7 +203,6 @@ macro(DeclareTargets) ${PATH_HACKRF_FIRMWARE_COMMON}/adc.c ${PATH_HACKRF_FIRMWARE_COMMON}/da7219.c ${PATH_HACKRF_FIRMWARE_COMMON}/max283x.c - ${PATH_HACKRF_FIRMWARE_COMMON}/u128.c ) if(BOARD STREQUAL "RAD1O") diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index 813a9453..ce24d879 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -36,8 +36,6 @@ #include #include #include -#include -#include #include #include #include @@ -428,8 +426,6 @@ int main(void) detect_hardware_platform(); board_id_t board_id = detected_platform(); - i2c_bus_start(&i2c0, &i2c_config_fast_clock); - pins_shutdown(); sgpio_pin_shutdown(&sgpio_config); rf_path_pin_shutdown(); @@ -491,9 +487,6 @@ int main(void) #endif cpu_clock_init(); - /* Clock speed has changed, adjust I2C clock */ - i2c_bus_start(&i2c0, &i2c_config_fast_clock); - /* Wake the M0 */ ipc_halt_m0(); ipc_start_m0((uint32_t) &__ram_m0_start__); diff --git a/firmware/hackrf_usb/usb_api_sweep.c b/firmware/hackrf_usb/usb_api_sweep.c index 1bea5dd2..0da2cf6e 100644 --- a/firmware/hackrf_usb/usb_api_sweep.c +++ b/firmware/hackrf_usb/usb_api_sweep.c @@ -132,7 +132,7 @@ usb_request_status_t usb_vendor_request_init_sweep( radio_reg_write( &radio, - RADIO_BANK_REQUESTED, + RADIO_BANK_ACTIVE, RADIO_FREQUENCY_RF, (sweep_freq + offset) * FP_ONE_HZ); usb_transfer_schedule_ack(endpoint->in); @@ -263,7 +263,7 @@ void sweep_mode(uint32_t seq) nvic_disable_irq(NVIC_USB0_IRQ); radio_reg_write( &radio, - RADIO_BANK_REQUESTED, + RADIO_BANK_ACTIVE, RADIO_FREQUENCY_RF, (sweep_freq + offset) * FP_ONE_HZ); nvic_enable_irq(NVIC_USB0_IRQ); diff --git a/firmware/hackrf_usb/usb_api_transceiver.c b/firmware/hackrf_usb/usb_api_transceiver.c index e72a408b..dbbbf661 100644 --- a/firmware/hackrf_usb/usb_api_transceiver.c +++ b/firmware/hackrf_usb/usb_api_transceiver.c @@ -94,12 +94,12 @@ usb_request_status_t usb_vendor_request_set_baseband_filter_bandwidth( (endpoint->setup.index << 16) | endpoint->setup.value; radio_reg_write( &radio, - RADIO_BANK_REQUESTED, + RADIO_BANK_ACTIVE, RADIO_BB_BANDWIDTH_TX, bandwidth); radio_reg_write( &radio, - RADIO_BANK_REQUESTED, + RADIO_BANK_ACTIVE, RADIO_BB_BANDWIDTH_RX, bandwidth); usb_transfer_schedule_ack(endpoint->in); @@ -123,22 +123,22 @@ usb_request_status_t usb_vendor_request_set_freq( set_freq_params.freq_mhz * 1000000ULL + set_freq_params.freq_hz; radio_reg_write( &radio, - RADIO_BANK_REQUESTED, + RADIO_BANK_ACTIVE, RADIO_FREQUENCY_RF, freq * FP_ONE_HZ); radio_reg_write( &radio, - RADIO_BANK_REQUESTED, + RADIO_BANK_ACTIVE, RADIO_FREQUENCY_IF, RADIO_UNSET); radio_reg_write( &radio, - RADIO_BANK_REQUESTED, + RADIO_BANK_ACTIVE, RADIO_FREQUENCY_LO, RADIO_UNSET); radio_reg_write( &radio, - RADIO_BANK_REQUESTED, + RADIO_BANK_ACTIVE, RADIO_IMAGE_REJECT, RADIO_UNSET); usb_transfer_schedule_ack(endpoint->in); @@ -160,17 +160,17 @@ usb_request_status_t usb_vendor_request_set_freq_explicit( } else if (stage == USB_TRANSFER_STAGE_DATA) { radio_reg_write( &radio, - RADIO_BANK_REQUESTED, + RADIO_BANK_ACTIVE, RADIO_FREQUENCY_IF, explicit_params.if_freq_hz * FP_ONE_HZ); radio_reg_write( &radio, - RADIO_BANK_REQUESTED, + RADIO_BANK_ACTIVE, RADIO_FREQUENCY_LO, explicit_params.lo_freq_hz * FP_ONE_HZ); radio_reg_write( &radio, - RADIO_BANK_REQUESTED, + RADIO_BANK_ACTIVE, RADIO_IMAGE_REJECT, explicit_params.path); usb_transfer_schedule_ack(endpoint->in); @@ -215,7 +215,7 @@ usb_request_status_t usb_vendor_request_set_sample_rate_frac( uint32_t numerator = set_sample_r_params.freq_hz; uint32_t denominator = set_sample_r_params.divider; uint64_t value = round_sample_rate(numerator, denominator); - radio_reg_write(&radio, RADIO_BANK_REQUESTED, RADIO_SAMPLE_RATE, value); + radio_reg_write(&radio, RADIO_BANK_ACTIVE, RADIO_SAMPLE_RATE, value); usb_transfer_schedule_ack(endpoint->in); } return USB_REQUEST_STATUS_OK; @@ -228,12 +228,12 @@ usb_request_status_t usb_vendor_request_set_amp_enable( if (stage == USB_TRANSFER_STAGE_SETUP) { radio_reg_write( &radio, - RADIO_BANK_REQUESTED, + RADIO_BANK_ACTIVE, RADIO_GAIN_TX_RF, endpoint->setup.value); radio_reg_write( &radio, - RADIO_BANK_REQUESTED, + RADIO_BANK_ACTIVE, RADIO_GAIN_RX_RF, endpoint->setup.value); usb_transfer_schedule_ack(endpoint->in); @@ -247,7 +247,7 @@ usb_request_status_t usb_vendor_request_set_lna_gain( { if (stage == USB_TRANSFER_STAGE_SETUP) { uint8_t gain = endpoint->setup.index; - radio_reg_write(&radio, RADIO_BANK_REQUESTED, RADIO_GAIN_RX_IF, gain); + radio_reg_write(&radio, RADIO_BANK_ACTIVE, RADIO_GAIN_RX_IF, gain); endpoint->buffer[0] = RADIO_OK; usb_transfer_schedule_block( endpoint->in, @@ -266,7 +266,7 @@ usb_request_status_t usb_vendor_request_set_vga_gain( { if (stage == USB_TRANSFER_STAGE_SETUP) { uint8_t gain = endpoint->setup.index; - radio_reg_write(&radio, RADIO_BANK_REQUESTED, RADIO_GAIN_RX_BB, gain); + radio_reg_write(&radio, RADIO_BANK_ACTIVE, RADIO_GAIN_RX_BB, gain); endpoint->buffer[0] = RADIO_OK; usb_transfer_schedule_block( endpoint->in, @@ -285,7 +285,7 @@ usb_request_status_t usb_vendor_request_set_txvga_gain( { if (stage == USB_TRANSFER_STAGE_SETUP) { uint8_t gain = endpoint->setup.index; - radio_reg_write(&radio, RADIO_BANK_REQUESTED, RADIO_GAIN_TX_IF, gain); + radio_reg_write(&radio, RADIO_BANK_ACTIVE, RADIO_GAIN_TX_IF, gain); endpoint->buffer[0] = RADIO_OK; usb_transfer_schedule_block( endpoint->in, @@ -315,7 +315,7 @@ usb_request_status_t usb_vendor_request_set_antenna_enable( if (stage == USB_TRANSFER_STAGE_SETUP) { radio_reg_write( &radio, - RADIO_BANK_REQUESTED, + RADIO_BANK_ACTIVE, RADIO_BIAS_TEE, endpoint->setup.value); usb_transfer_schedule_ack(endpoint->in); @@ -427,7 +427,7 @@ usb_request_status_t usb_vendor_request_set_hw_sync_mode( if (stage == USB_TRANSFER_STAGE_SETUP) { radio_reg_write( &radio, - RADIO_BANK_REQUESTED, + RADIO_BANK_ACTIVE, RADIO_TRIGGER, endpoint->setup.value); usb_transfer_schedule_ack(endpoint->in); diff --git a/firmware/hackrf_usb/usb_descriptor.c b/firmware/hackrf_usb/usb_descriptor.c index dde22e6e..005babb3 100644 --- a/firmware/hackrf_usb/usb_descriptor.c +++ b/firmware/hackrf_usb/usb_descriptor.c @@ -28,7 +28,7 @@ #define USB_VENDOR_ID (0x1D50) -#define USB_API_VERSION (0x0113) +#define USB_API_VERSION (0x0112) #define USB_WORD(x) (x & 0xFF), ((x >> 8) & 0xFF) diff --git a/host/hackrf-tools/src/hackrf_debug.c b/host/hackrf-tools/src/hackrf_debug.c index 5f8785b5..52ede9cb 100644 --- a/host/hackrf-tools/src/hackrf_debug.c +++ b/host/hackrf-tools/src/hackrf_debug.c @@ -501,7 +501,7 @@ int radio_read_register( return result; } -#define RADIO_NUM_REGS (24) +#define RADIO_NUM_REGS (23) int radio_read_registers(hackrf_device* device, const uint8_t bank) { diff --git a/host/libhackrf/src/hackrf.c b/host/libhackrf/src/hackrf.c index 4018ac63..7bafd5f3 100644 --- a/host/libhackrf/src/hackrf.c +++ b/host/libhackrf/src/hackrf.c @@ -57,7 +57,6 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSI #define DEFAULT_REQUEST_TIMEOUT 100 #define CPLD_WRITE_TIMEOUT 10000 #define SPIFLASH_WRITE_TIMEOUT 50000 // W25Q32JV max chip erase time -#define FPGA_BITSTREAM_TIMEOUT 500 // TODO: Factor this into a shared #include so that firmware can use // the same values. @@ -3497,7 +3496,7 @@ int ADDCALL hackrf_set_fpga_bitstream(hackrf_device* device, const uint8_t index 0, NULL, 0, - FPGA_BITSTREAM_TIMEOUT); + DEFAULT_REQUEST_TIMEOUT); if (result != 0) { last_libusb_error = result;