From c5834e6c1bab5f049e1acc6401fb09aebf7e7fa5 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 5 Feb 2026 00:14:42 +0100 Subject: [PATCH 01/15] Fix nr_srssim linking problems when building with E2 support In this case, there are a number of linker errors: /usr/bin/ld: libL2_NR.a(rrc_gNB.c.o): in function `nr_rrc_transfer_protected_rrc_message': /home/richie/oai/openair2/RRC/NR/rrc_gNB.c:330:(.text+0x6f6): undefined reference to `signal_rrc_msg' However, nr_srssim does not need RRC, while it is being linked in. Thus, link without nr_rrc and L2. For the remaining two linker problems: - provide a definition of NR_IF_Module_init() as in most other simulators - move rrc_get_max_nr_csrs() to nr_common.c. It is already declared in the corresponding header, and itself does not have anything to do with RRC radio configuration, therefore it does not belong to nr_radio_config.c --- CMakeLists.txt | 2 +- common/utils/nr/nr_common.c | 25 ++++++++++++++++++++ openair1/SIMULATION/NR_PHY/srssim.c | 2 ++ openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c | 25 -------------------- 4 files changed, 28 insertions(+), 26 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bae1c590bc..154493f6d9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2080,7 +2080,7 @@ add_executable(nr_srssim ) target_link_libraries(nr_srssim PRIVATE - -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_UE_NR MAC_NR_COMMON nr_rrc L2_NR -lz -Wl,--end-group + -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_UE_NR MAC_NR_COMMON -lz -Wl,--end-group m pthread ITTI dl nr_ue_phy_meas physim_common ) diff --git a/common/utils/nr/nr_common.c b/common/utils/nr/nr_common.c index 96b8681cff..2beee06c26 100644 --- a/common/utils/nr/nr_common.c +++ b/common/utils/nr/nr_common.c @@ -1447,6 +1447,31 @@ unsigned short get_N_b_srs(int c_srs, int b_srs) { return srs_bandwidth_config[c_srs][b_srs][1]; } +// TODO: Implement to b_SRS = 1 and b_SRS = 2 +long rrc_get_max_nr_csrs(const int max_rbs, const long b_SRS) +{ + if(b_SRS>0) { + LOG_E(NR_RRC,"rrc_get_max_nr_csrs(): Not implemented yet for b_SRS>0\n"); + return 0; // This c_srs is always valid + } + + const uint16_t m_SRS[64] = { 4, 8, 12, 16, 16, 20, 24, 24, 28, 32, 36, 40, 48, 48, 52, 56, 60, 64, 72, 72, 76, 80, 88, + 96, 96, 104, 112, 120, 120, 120, 128, 128, 128, 132, 136, 144, 144, 144, 144, 152, 160, + 160, 160, 168, 176, 184, 192, 192, 192, 192, 208, 216, 224, 240, 240, 240, 240, 256, 256, + 256, 264, 272, 272, 272 }; + + long c_srs = 0; + uint16_t m = 4; + for(int c = 1; c<64; c++) { + if(m_SRS[c]>m && m_SRS[c]ext1->maxMIMO_Layers = min(maxMIMO_layers, ue_supported_layers); } -// TODO: Implement to b_SRS = 1 and b_SRS = 2 -long rrc_get_max_nr_csrs(const int max_rbs, const long b_SRS) { - - if(b_SRS>0) { - LOG_E(NR_RRC,"rrc_get_max_nr_csrs(): Not implemented yet for b_SRS>0\n"); - return 0; // This c_srs is always valid - } - - const uint16_t m_SRS[64] = { 4, 8, 12, 16, 16, 20, 24, 24, 28, 32, 36, 40, 48, 48, 52, 56, 60, 64, 72, 72, 76, 80, 88, - 96, 96, 104, 112, 120, 120, 120, 128, 128, 128, 132, 136, 144, 144, 144, 144, 152, 160, - 160, 160, 168, 176, 184, 192, 192, 192, 192, 208, 216, 224, 240, 240, 240, 240, 256, 256, - 256, 264, 272, 272, 272 }; - - long c_srs = 0; - uint16_t m = 4; - for(int c = 1; c<64; c++) { - if(m_SRS[c]>m && m_SRS[c] Date: Thu, 5 Feb 2026 08:29:06 +0100 Subject: [PATCH 02/15] Remove option --disable-hardware-dependency --- cmake_targets/build_oai | 13 +------------ cmake_targets/tools/build_helper | 4 ---- 2 files changed, 1 insertion(+), 16 deletions(-) diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index c6d1276e88..44ed349594 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -38,7 +38,6 @@ conf_nvram_path=$OPENAIR_DIR/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf HW="" BUILD_DIR=ran_build -DISABLE_HARDWARE_DEPENDENCY="False" CMAKE_BUILD_TYPE="RelWithDebInfo" CMAKE_CMD="$CMAKE" OPTIONAL_LIBRARIES="telnetsrv enbscope uescope nrscope ldpc_cuda ldpc_aal ldpc_xdma websrv oai_iqplayer imscope imscope_record" @@ -328,10 +327,6 @@ function main() { CMAKE_CMD="$CMAKE_CMD -DT_TRACER=False" echo_info "Disabling the T tracer" shift 1;; - --disable-hardware-dependency) - echo_info "Disabling hardware dependency for compiling software" - DISABLE_HARDWARE_DEPENDENCY="True" - shift 1;; --ue-trace) CMAKE_CMD="$CMAKE_CMD -DUE_DEBUG_TRACE=False" echo_info "Enabling UE trace for debug" @@ -427,23 +422,17 @@ function main() { if [ "$HW" == "OAI_USRP" ] ; then echo_info "installing packages for USRP support" check_install_usrp_uhd_driver - if [ ! -v BUILD_UHD_FROM_SOURCE ] && [ ! "$DISABLE_HARDWARE_DEPENDENCY" == "True" ]; then + if [ ! -v BUILD_UHD_FROM_SOURCE ]; then install_usrp_uhd_driver $UHD_IMAGES_DIR fi fi if [ "$HW" == "OAI_BLADERF" ] ; then echo_info "installing packages for BLADERF support" check_install_bladerf_driver - if [ ! "$DISABLE_HARDWARE_DEPENDENCY" == "True" ]; then - flash_firmware_bladerf - fi fi if [ "$HW" == "OAI_IRIS" ] ; then echo_info "installing packages for IRIS support" check_install_soapy - #if [ ! "$DISABLE_HARDWARE_DEPENDENCY" == "True" ]; then - # flash_firmware_iris - #fi fi fi diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index 3443d06c43..5301af660d 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -368,10 +368,6 @@ check_install_bladerf_driver(){ fi } -flash_firmware_bladerf() { - $SUDO bladeRF-cli --flash-firmware /usr/share/Nuand/bladeRF/bladeRF_fw.img -} - check_install_lmssdr_driver(){ if ( [ -d "/usr/local/include/lime" ] && [ -f "/usr/local/include/lime/LimeSuite.h" ] ) From 38975ef1207c55b285cda842618c0df9f3af751f Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 5 Feb 2026 02:04:18 +0100 Subject: [PATCH 03/15] Allow installation of multiple hardwares in same build_oai invocation There is no reason to not allow ./build_oai -I -w USRP -w BLADERF To install USRP and BladeRF together (which will be used in the CI in a later commit). Fix this. --- cmake_targets/build_oai | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index 44ed349594..c9e268407d 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -36,7 +36,7 @@ set_openair_env # Variables for UE data generation conf_nvram_path=$OPENAIR_DIR/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf -HW="" +HWs="" BUILD_DIR=ran_build CMAKE_BUILD_TYPE="RelWithDebInfo" CMAKE_CMD="$CMAKE" @@ -253,22 +253,22 @@ function main() { -w | --hardware) case "$2" in "USRP" | "BLADERF" | "LMSSDR" | "IRIS") - HW="OAI_"$2 + HWs+=" OAI_"$2 TARGET_LIST="$TARGET_LIST oai_${2,,}devif" # ,, makes lowercase CMAKE_CMD="$CMAKE_CMD -DOAI_$2=ON" ;; "SIMU") - HW="OAI_"$2 + HWs+=" OAI_"$2 TARGET_LIST="$TARGET_LIST rfsimulator" CMAKE_CMD="$CMAKE_CMD -DOAI_$2=ON" ;; "AW2SORI") - HW="OAI_"$2 + HWs=" OAI_"$2 TARGET_LIST="$TARGET_LIST aw2sori_transpro" CMAKE_CMD="$CMAKE_CMD -DOAI_$2=ON" ;; "AERIAL"|"Aerial"|"aerial") - HW="OAI_AERIAL" + HWs+=" OAI_AERIAL" CMAKE_CMD="$CMAKE_CMD -DOAI_AERIAL=ON" ;; "None") @@ -419,21 +419,23 @@ function main() { echo_info "installing LTTng" install_lttng $1 fi - if [ "$HW" == "OAI_USRP" ] ; then - echo_info "installing packages for USRP support" - check_install_usrp_uhd_driver - if [ ! -v BUILD_UHD_FROM_SOURCE ]; then - install_usrp_uhd_driver $UHD_IMAGES_DIR + for HW in $HWs; do + if [ "$HW" == "OAI_USRP" ] ; then + echo_info "installing packages for USRP support" + check_install_usrp_uhd_driver + if [ ! -v BUILD_UHD_FROM_SOURCE ]; then + install_usrp_uhd_driver $UHD_IMAGES_DIR + fi + elif [ "$HW" == "OAI_BLADERF" ] ; then + echo_info "installing packages for BLADERF support" + check_install_bladerf_driver + elif [ "$HW" == "OAI_IRIS" ] ; then + echo_info "installing packages for IRIS support" + check_install_soapy + else + echo_warning "no installation scripts for hardware $HW" fi - fi - if [ "$HW" == "OAI_BLADERF" ] ; then - echo_info "installing packages for BLADERF support" - check_install_bladerf_driver - fi - if [ "$HW" == "OAI_IRIS" ] ; then - echo_info "installing packages for IRIS support" - check_install_soapy - fi + done fi if [ "$INSTALL_OPTIONAL" = "1" ] ; then From 4e5d92401b0cae846012f060d55b1bf99a3309c3 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 4 Feb 2026 09:33:03 +0100 Subject: [PATCH 04/15] Add Debian 12 to list of supported distributions --- cmake_targets/tools/build_helper | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index 5301af660d..4e832891eb 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -107,6 +107,7 @@ check_supported_distribution() { "ubuntu22.04") return 0 ;; "ubuntu20.04") return 0 ;; "debian11") return 0 ;; + "debian12") return 0 ;; "fedora41") return 0 ;; "fedora40") return 0 ;; "rhel8.2") return 0 ;; @@ -449,7 +450,7 @@ check_install_additional_tools (){ local optional_packages="" if [[ "$OS_BASEDISTRO" == "debian" ]]; then case "$(get_distribution_release)" in - "ubuntu20.04" | "ubuntu22.04" | "debian11" ) + "ubuntu20.04" | "ubuntu22.04" | "debian11" | "debian12") optional_packages="python3 python3-pip python3-dev python3-scipy python3-matplotlib python3-pyroute2 universal-ctags" ;; esac @@ -492,7 +493,7 @@ check_install_oai_software() { if [[ "$OS_BASEDISTRO" == "debian" ]]; then $SUDO apt install -y software-properties-common case "$(get_distribution_release)" in - "debian11") + "debian11" | "debian12") specific_packages="libz-dev" ;; esac From 93c37e96e6ee3bfe861b1760d190816b788e53e5 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 4 Feb 2026 11:32:27 +0100 Subject: [PATCH 05/15] Make BladeRF library compile Fixes: dd8a25524a97 ("remove dead code in common_lib.h") --- radio/BLADERF/bladerf_lib.c | 1 - 1 file changed, 1 deletion(-) diff --git a/radio/BLADERF/bladerf_lib.c b/radio/BLADERF/bladerf_lib.c index 2298287b5a..708d43583e 100644 --- a/radio/BLADERF/bladerf_lib.c +++ b/radio/BLADERF/bladerf_lib.c @@ -1127,7 +1127,6 @@ int device_init(openair0_device_t *device, openair0_config_t *openair0_cfg) bladerf_log_set_verbosity(BLADERF_LOG_LEVEL_INFO); printf("BLADERF: Initializing openair0_device_t\n"); - device->Mod_id = num_devices++; device->type = BLADERF_DEV; device->trx_start_func = trx_brf_start; device->trx_end_func = trx_brf_end; From 5fdec24b52b7abf34bcc91b70301b79401ec4f7a Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 4 Feb 2026 09:35:03 +0100 Subject: [PATCH 06/15] Delete unused or useless code Note: device->Mod_id is deleted in !3831. The calibration table has no purpose. Co-authored-by: Brice Robert --- radio/BLADERF/bladerf_lib.c | 778 +++--------------------------------- radio/BLADERF/bladerf_lib.h | 122 ------ 2 files changed, 59 insertions(+), 841 deletions(-) delete mode 100644 radio/BLADERF/bladerf_lib.h diff --git a/radio/BLADERF/bladerf_lib.c b/radio/BLADERF/bladerf_lib.c index 708d43583e..5bb2f069dc 100644 --- a/radio/BLADERF/bladerf_lib.c +++ b/radio/BLADERF/bladerf_lib.c @@ -19,60 +19,72 @@ * contact@openairinterface.org */ -/** bladerf_lib.c - * - * Author: navid nikaein - */ - - #include #include -#include -#include "bladerf_lib.h" -#include "math.h" -#include "PHY/sse_intrin.h" +#include + +#include +#include "common_lib.h" + +/*! \brief BladeRF specific data structure */ +typedef struct { + //! opaque BladeRF device struct. An empty ("") or NULL device identifier will result in the first encountered device being opened + //! (using the first discovered backend) + struct bladerf *dev; + + //! Number of buffers + unsigned int num_buffers; + //! Buffer size + unsigned int buffer_size; + //! Number of transfers + unsigned int num_transfers; + //! RX timeout + unsigned int rx_timeout_ms; + //! TX timeout + unsigned int tx_timeout_ms; + //! Metadata for RX + struct bladerf_metadata meta_rx; + //! Metadata for TX + struct bladerf_metadata meta_tx; + //! Sample rate + unsigned int sample_rate; + + // -------------------------------- + // Debug and output control + // -------------------------------- + //! Number of underflows + int num_underflows; + //! Number of overflows + int num_overflows; + //! number of RX errors + int num_rx_errors; + //! Number of TX errors + int num_tx_errors; + + //! timestamp of current TX + uint64_t tx_current_ts; + //! timestamp of current RX + uint64_t rx_current_ts; + //! number of actual samples transmitted + uint64_t tx_actual_nsamps; + //! number of actual samples received + uint64_t rx_actual_nsamps; + //! number of TX samples + uint64_t tx_nsamps; + //! number of RX samples + uint64_t rx_nsamps; + //! number of TX count + uint64_t tx_count; + //! number of RX count + uint64_t rx_count; +} brf_state_t; + +int brf_error(int status); /** @addtogroup _BLADERF_PHY_RF_INTERFACE_ * @{ */ -//! Number of BladeRF devices -int num_devices=0; - -/*These items configure the underlying asynch stream used by the the sync interface. - */ - -/*! \brief BladeRF Init function (not used at the moment) - * \param device RF frontend parameters set by application - * \returns 0 on success - */ -int trx_brf_init(openair0_device_t *device) -{ - return 0; -} - - -/*! \brief get current timestamp - *\param device the hardware to use - *\param module the bladeRf module - *\returns timestamp of BladeRF - */ -openair0_timestamp_t trx_get_timestamp(openair0_device_t *device, bladerf_module module) -{ - int status; - struct bladerf_metadata meta; - brf_state_t *brf = (brf_state_t*)device->priv; - memset(&meta, 0, sizeof(meta)); - - if ((status=bladerf_get_timestamp(brf->dev, module, &meta.timestamp)) != 0) { - fprintf(stderr,"Failed to get current %s timestamp: %s\n",(module == BLADERF_MODULE_RX ) ? "RX" : "TX", bladerf_strerror(status)); - return -1; - } // else {printf("Current RX timestampe 0x%016"PRIx64"\n", meta.timestamp); } - - return meta.timestamp; -} - - /*! \brief Start BladeRF * \param device the hardware to use * \returns 0 on success @@ -314,624 +326,6 @@ int trx_brf_write_init(openair0_device_t *device) return 0; } -#define RXDCLENGTH 16384 -int16_t cos_fsover8[8] = {2047, 1447, 0, -1448, -2047, -1448, 0, 1447}; -int16_t cos_3fsover8[8] = {2047, -1448, 0, 1447, -2047, 1447, 0, -1448}; - -/*! \brief calibration table for BladeRF */ -rx_gain_calib_table_t calib_table_fx4[] = { - {2300000000.0,53.5}, - {1880000000.0,57.0}, - {816000000.0,73.0}, - {-1,0} -}; - - -/*! \brief set RX gain offset from calibration table - * \param openair0_cfg RF frontend parameters set by application - * \param chain_index RF chain ID - */ -void set_rx_gain_offset(openair0_config_t *openair0_cfg, - int chain_index) -{ - int i=0; - // loop through calibration table to find best adjustment factor for RX frequency - double min_diff = 6e9,diff; - - while (openair0_cfg->rx_gain_calib_table[i].freq>0) { - diff = fabs(openair0_cfg->rx_freq[chain_index] - openair0_cfg->rx_gain_calib_table[i].freq); - printf("cal %d: freq %f, offset %f, diff %f\n", - i, - openair0_cfg->rx_gain_calib_table[i].freq, - openair0_cfg->rx_gain_calib_table[i].offset,diff); - if (min_diff > diff) { - min_diff = diff; - openair0_cfg->rx_gain_offset[chain_index] = openair0_cfg->rx_gain_calib_table[i].offset; - } - i++; - } - -} - - -/*! \brief Calibrate LMSSDR RF - * \param device the hardware to use - */ -void calibrate_rf(openair0_device_t *device) -{ - /* TODO: this function does not seem to work. Disabled until fixed. */ - return; - - brf_state_t *brf = (brf_state_t *)device->priv; - openair0_timestamp_t ptimestamp; - int16_t *calib_buffp,*calib_tx_buffp; - int16_t calib_buff[2*RXDCLENGTH]; - int16_t calib_tx_buff[2*RXDCLENGTH]; - int i,j,offI,offQ,offIold,offQold,offInew,offQnew,offphase,offphaseold,offphasenew,offgain,offgainold,offgainnew; - int32_t meanI,meanQ,meanIold,meanQold; - int cnt=0,loop; - - // put TX on a far-away frequency to avoid interference in RX band - bladerf_set_frequency(brf->dev,BLADERF_MODULE_TX, (unsigned int) device->openair0_cfg->rx_freq[0] + 200e6); - // Set gains to close to max - bladerf_set_gain(brf->dev, BLADERF_MODULE_RX, 60); - bladerf_set_gain(brf->dev, BLADERF_MODULE_TX, 60); - - // fill TX buffer with fs/8 complex sinusoid - j=0; - for (i=0; idev,BLADERF_MODULE_RX,BLADERF_CORR_LMS_DCOFF_I,offIold); - bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_LMS_DCOFF_Q,offQold); - for (i=0; i<10; i++) - trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); - - for (meanIold=meanQold=i=j=0; i (%d,%d)\n",offIold,offQold,meanIold,meanQold); - - offI=offQ=-2048; - bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_LMS_DCOFF_I,offI); - bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_LMS_DCOFF_Q,offQ); - for (i=0; i<10; i++) - trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); - - for (meanI=meanQ=i=j=0; i (%d,%d)\n",offI,offQ,meanI,meanQ); - - while (cnt++ < 12) { - - offInew=(offIold+offI)>>1; - offQnew=(offQold+offQ)>>1; - - if (meanI*meanI < meanIold*meanIold) { - meanIold = meanI; - offIold = offI; - printf("[BRF] *** RX DC: offI %d => %d\n",offIold,meanI); - } - if (meanQ*meanQ < meanQold*meanQold) { - meanQold = meanQ; - offQold = offQ; - printf("[BRF] *** RX DC: offQ %d => %d\n",offQold,meanQ); - } - offI = offInew; - offQ = offQnew; - bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_LMS_DCOFF_I,offI); - bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_LMS_DCOFF_Q,offQ); - - for (i=0; i<10; i++) - trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); - - for (meanI=meanQ=i=j=0; i (%d,%d)\n",offI,offQ,meanI,meanQ); - } - - printf("[BRF] RX DC: (%d,%d) => (%d,%d)\n",offIold,offQold,meanIold,meanQold); - bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_LMS_DCOFF_I,offIold); - bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_LMS_DCOFF_Q,offQold); - - // TX DC offset - // PUT TX as f_RX + fs/4 - // loop back BLADERF_LB_RF_LNA1 - bladerf_set_frequency(brf->dev,BLADERF_MODULE_TX, (unsigned int) device->openair0_cfg->rx_freq[0] + (unsigned int) device->openair0_cfg->sample_rate/4); - bladerf_set_loopback (brf->dev,BLADERF_LB_RF_LNA1); - - offIold=2048; - bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_LMS_DCOFF_I,offIold); - for (i=0; i<10; i++) { - trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); - trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0); - } - for (meanIold=meanQold=i=j=0; i (%d,%d)\n",offIold,meanIold,meanQold); - - offI=-2048; - bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_LMS_DCOFF_I,offI); - for (i=0; i<10; i++) { - trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); - trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0); - } - for (meanI=meanQ=i=j=0; i (%d,%d)\n",offI,meanI,meanQ); - cnt = 0; - while (cnt++ < 12) { - - offInew=(offIold+offI)>>1; - if (meanI*meanI+meanQ*meanQ < meanIold*meanIold +meanQold*meanQold) { - printf("[BRF] TX DC (offI): ([%d,%d]) => %d : %d\n",offIold,offI,offInew,meanI*meanI+meanQ*meanQ); - meanIold = meanI; - meanQold = meanQ; - offIold = offI; - } - offI = offInew; - bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_LMS_DCOFF_I,offI); - - for (i=0; i<10; i++) { - trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); - trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0); - } - for (meanI=meanQ=i=j=0; i (%d,%d)\n",offI,meanI,meanQ); - } - - bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_LMS_DCOFF_I,offIold); - - offQold=2048; - bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_LMS_DCOFF_Q,offQold); - for (i=0; i<10; i++) { - trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); - trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0); - } - // project on fs/4 - for (meanIold=meanQold=i=j=0; i (%d,%d)\n",offQold,meanIold,meanQold); - - offQ=-2048; - bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_LMS_DCOFF_Q,offQ); - for (i=0; i<10; i++) { - trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); - trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0); - } - for (meanI=meanQ=i=j=0; i (%d,%d)\n",offQ,meanI,meanQ); - - cnt=0; - while (cnt++ < 12) { - - offQnew=(offQold+offQ)>>1; - if (meanI*meanI+meanQ*meanQ < meanIold*meanIold +meanQold*meanQold) { - printf("[BRF] TX DC (offQ): ([%d,%d]) => %d : %d\n",offQold,offQ,offQnew,meanI*meanI+meanQ*meanQ); - - meanIold = meanI; - meanQold = meanQ; - offQold = offQ; - } - offQ = offQnew; - bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_LMS_DCOFF_Q,offQ); - - for (i=0; i<10; i++) { - trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); - trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0); - } - for (meanI=meanQ=i=j=0; i (%d,%d)\n",offQ,meanI,meanQ); - } - - printf("[BRF] TX DC: (%d,%d) => (%d,%d)\n",offIold,offQold,meanIold,meanQold); - - bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_LMS_DCOFF_Q,offQold); - - // TX IQ imbalance - for (loop=0; loop<2; loop++) { - offphaseold=4096; - bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_FPGA_PHASE,offphaseold); - for (i=0; i<10; i++) { - trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); - trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0); - } - // project on fs/8 (Image of TX signal in +ve frequencies) - for (meanIold=meanQold=i=j=0; i>11; - meanQold+= (calib_buff[j]*cos_fsover8[(i+2)&7] + calib_buff[j+1]*cos_fsover8[i&7])>>11; - j+=2; - } - - meanIold/=RXDCLENGTH; - meanQold/=RXDCLENGTH; - printf("[BRF] TX IQ (offphase): %d => (%d,%d)\n",offphaseold,meanIold,meanQold); - - offphase=-4096; - bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_FPGA_PHASE,offphase); - for (i=0; i<10; i++) { - trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); - trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0); - } - // project on fs/8 (Image of TX signal in +ve frequencies) - for (meanI=meanQ=i=j=0; i>11; - meanQ+= (calib_buff[j]*cos_fsover8[(i+2)&7] + calib_buff[j+1]*cos_fsover8[i&7])>>11; - j+=2; - } - - meanI/=RXDCLENGTH; - meanQ/=RXDCLENGTH; - printf("[BRF] TX IQ (offphase): %d => (%d,%d)\n",offphase,meanI,meanQ); - - cnt=0; - while (cnt++ < 13) { - - offphasenew=(offphaseold+offphase)>>1; - printf("[BRF] TX IQ (offphase): ([%d,%d]) => %d : %d\n",offphaseold,offphase,offphasenew,meanI*meanI+meanQ*meanQ); - if (meanI*meanI+meanQ*meanQ < meanIold*meanIold +meanQold*meanQold) { - - - meanIold = meanI; - meanQold = meanQ; - offphaseold = offphase; - } - offphase = offphasenew; - bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_FPGA_PHASE,offphase); - - for (i=0; i<10; i++) { - trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); - trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0); - } - // project on fs/8 (Image of TX signal in +ve frequencies) - for (meanI=meanQ=i=j=0; i>11; - meanQ+= (calib_buff[j]*cos_fsover8[(i+2)&7] + calib_buff[j+1]*cos_fsover8[i&7])>>11; - j+=2; - } - meanI/=RXDCLENGTH; - meanQ/=RXDCLENGTH; - - // printf("[BRF] TX DC (offQ): %d => (%d,%d)\n",offQ,meanI,meanQ); - } - - printf("[BRF] TX IQ offphase: %d => (%d,%d)\n",offphaseold,meanIold,meanQold); - - bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_FPGA_PHASE,offphaseold); - - offgainold=4096; - bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_FPGA_GAIN,offgainold); - for (i=0; i<10; i++) { - trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); - trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0); - } - // project on fs/8 (Image of TX signal in +ve frequencies) - for (meanIold=meanQold=i=j=0; i>11; - meanQold+= (calib_buff[j]*cos_fsover8[(i+2)&7] + calib_buff[j+1]*cos_fsover8[i&7])>>11; - j+=2; - } - - meanIold/=RXDCLENGTH; - meanQold/=RXDCLENGTH; - printf("[BRF] TX IQ (offgain): %d => (%d,%d)\n",offgainold,meanIold,meanQold); - - offgain=-4096; - bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_FPGA_GAIN,offgain); - for (i=0; i<10; i++) { - trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); - trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0); - } - // project on fs/8 (Image of TX signal in +ve frequencies) - for (meanI=meanQ=i=j=0; i>11; - meanQ+= (calib_buff[j]*cos_fsover8[(i+2)&7] + calib_buff[j+1]*cos_fsover8[i&7])>>11; - j+=2; - } - - meanI/=RXDCLENGTH; - meanQ/=RXDCLENGTH; - printf("[BRF] TX IQ (offgain): %d => (%d,%d)\n",offgain,meanI,meanQ); - - cnt=0; - while (cnt++ < 13) { - - offgainnew=(offgainold+offgain)>>1; - if (meanI*meanI+meanQ*meanQ < meanIold*meanIold +meanQold*meanQold) { - printf("[BRF] TX IQ (offgain): ([%d,%d]) => %d : %d\n",offgainold,offgain,offgainnew,meanI*meanI+meanQ*meanQ); - - meanIold = meanI; - meanQold = meanQ; - offgainold = offgain; - } - offgain = offgainnew; - bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_FPGA_GAIN,offgain); - - for (i=0; i<10; i++) { - trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); - trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0); - } - // project on fs/8 (Image of TX signal in +ve frequencies) - for (meanI=meanQ=i=j=0; i>11; - meanQ+= (calib_buff[j]*cos_fsover8[(i+2)&7] + calib_buff[j+1]*cos_fsover8[i&7])>>11; - j+=2; - } - meanI/=RXDCLENGTH; - meanQ/=RXDCLENGTH; - - // printf("[BRF] TX DC (offQ): %d => (%d,%d)\n",offQ,meanI,meanQ); - } - - printf("[BRF] TX IQ offgain: %d => (%d,%d)\n",offgainold,meanIold,meanQold); - - bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_FPGA_GAIN,offgainold); - } - - // RX IQ imbalance - for (loop=0; loop<2; loop++) { - offphaseold=4096; - bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_FPGA_PHASE,offphaseold); - for (i=0; i<10; i++) { - trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); - trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0); - } - // project on -3fs/8 (Image of TX signal in -ve frequencies) - for (meanIold=meanQold=i=j=0; i>11; - meanQold+= (calib_buff[j]*cos_3fsover8[(i+2)&7] + calib_buff[j+1]*cos_3fsover8[i&7])>>11; - j+=2; - } - - meanIold/=RXDCLENGTH; - meanQold/=RXDCLENGTH; - printf("[BRF] RX IQ (offphase): %d => (%d,%d)\n",offphaseold,meanIold,meanQold); - - offphase=-4096; - bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_FPGA_PHASE,offphase); - for (i=0; i<10; i++) { - trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); - trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0); - } - // project on -3fs/8 (Image of TX signal in -ve frequencies) - for (meanI=meanQ=i=j=0; i>11; - meanQ+= (calib_buff[j]*cos_3fsover8[(i+2)&7] + calib_buff[j+1]*cos_3fsover8[i&7])>>11; - j+=2; - } - - meanI/=RXDCLENGTH; - meanQ/=RXDCLENGTH; - printf("[BRF] RX IQ (offphase): %d => (%d,%d)\n",offphase,meanI,meanQ); - - cnt=0; - while (cnt++ < 13) { - - offphasenew=(offphaseold+offphase)>>1; - printf("[BRF] RX IQ (offphase): ([%d,%d]) => %d : %d\n",offphaseold,offphase,offphasenew,meanI*meanI+meanQ*meanQ); - if (meanI*meanI+meanQ*meanQ < meanIold*meanIold +meanQold*meanQold) { - - - meanIold = meanI; - meanQold = meanQ; - offphaseold = offphase; - } - offphase = offphasenew; - bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_FPGA_PHASE,offphase); - - for (i=0; i<10; i++) { - trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); - trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0); - } - // project on -3fs/8 (Image of TX signal in -ve frequencies) - for (meanI=meanQ=i=j=0; i>11; - meanQ+= (calib_buff[j]*cos_3fsover8[(i+2)&7] + calib_buff[j+1]*cos_3fsover8[i&7])>>11; - j+=2; - } - meanI/=RXDCLENGTH; - meanQ/=RXDCLENGTH; - - // printf("[BRF] TX DC (offQ): %d => (%d,%d)\n",offQ,meanI,meanQ); - } - - printf("[BRF] RX IQ offphase: %d => (%d,%d)\n",offphaseold,meanIold,meanQold); - - bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_FPGA_PHASE,offphaseold); - - offgainold=4096; - bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_FPGA_GAIN,offgainold); - for (i=0; i<10; i++) { - trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); - trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0,0); - } - // project on -3fs/8 (Image of TX signal in +ve frequencies) - for (meanIold=meanQold=i=j=0; i>11; - meanQold+= (calib_buff[j]*cos_3fsover8[(i+2)&7] + calib_buff[j+1]*cos_3fsover8[i&7])>>11; - j+=2; - } - - meanIold/=RXDCLENGTH; - meanQold/=RXDCLENGTH; - printf("[BRF] RX IQ (offgain): %d => (%d,%d)\n",offgainold,meanIold,meanQold); - - offgain=-4096; - bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_FPGA_GAIN,offgain); - for (i=0; i<10; i++) { - trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); - trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0); - } - // project on 3fs/8 (Image of TX signal in -ve frequencies) - for (meanI=meanQ=i=j=0; i>11; - meanQ+= (calib_buff[j]*cos_3fsover8[(i+2)&7] + calib_buff[j+1]*cos_3fsover8[i&7])>>11; - j+=2; - } - - meanI/=RXDCLENGTH; - meanQ/=RXDCLENGTH; - printf("[BRF] RX IQ (offgain): %d => (%d,%d)\n",offgain,meanI,meanQ); - - cnt=0; - while (cnt++ < 13) { - - offgainnew=(offgainold+offgain)>>1; - if (meanI*meanI+meanQ*meanQ < meanIold*meanIold +meanQold*meanQold) { - printf("[BRF] RX IQ (offgain): ([%d,%d]) => %d : %d\n",offgainold,offgain,offgainnew,meanI*meanI+meanQ*meanQ); - - meanIold = meanI; - meanQold = meanQ; - offgainold = offgain; - } - offgain = offgainnew; - bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_FPGA_GAIN,offgain); - - for (i=0; i<10; i++) { - trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); - trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0); - } - // project on -3fs/8 (Image of TX signal in -ve frequencies) - for (meanI=meanQ=i=j=0; i>11; - meanQ+= (calib_buff[j]*cos_3fsover8[(i+2)&7] + calib_buff[j+1]*cos_3fsover8[i&7])>>11; - j+=2; - } - meanI/=RXDCLENGTH; - meanQ/=RXDCLENGTH; - - // printf("[BRF] TX DC (offQ): %d => (%d,%d)\n",offQ,meanI,meanQ); - } - - printf("[BRF] RX IQ offgain: %d => (%d,%d)\n",offgainold,meanIold,meanQold); - - bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_FPGA_GAIN,offgainold); - } - - bladerf_set_frequency(brf->dev,BLADERF_MODULE_TX, (unsigned int) device->openair0_cfg->tx_freq[0]); - bladerf_set_loopback(brf->dev,BLADERF_LB_NONE); - bladerf_set_gain(brf->dev, BLADERF_MODULE_RX, (unsigned int) device->openair0_cfg->rx_gain[0]-device->openair0_cfg[0].rx_gain_offset[0]); - bladerf_set_gain(brf->dev, BLADERF_MODULE_TX, (unsigned int) device->openair0_cfg->tx_gain[0]); - // LOG_M("blade_rf_test.m","rxs",calib_buff,RXDCLENGTH,1,1); -} - - /*! \brief Initialize Openair BLADERF target. It returns 0 if OK * \param device the hardware to use * \param openair0_cfg RF frontend parameters set by application @@ -969,7 +363,6 @@ int device_init(openair0_device_t *device, openair0_config_t *openair0_cfg) exit(-1); break; } - openair0_cfg->rx_gain_calib_table = calib_table_fx4; // The number of buffers to use in the underlying data stream brf->num_buffers = 128; @@ -1030,7 +423,6 @@ int device_init(openair0_device_t *device, openair0_config_t *openair0_cfg) } else printf("[BRF] set RX bandwidth to %u, %u\n",(unsigned int)openair0_cfg->rx_bw*2, actual_value); - set_rx_gain_offset(&openair0_cfg[0],0); if ((status=bladerf_set_gain(brf->dev, BLADERF_MODULE_RX, (int) openair0_cfg->rx_gain[0]-openair0_cfg[0].rx_gain_offset[0])) != 0) { fprintf(stderr,"Failed to set RX gain: %s\n",bladerf_strerror(status)); brf_error(status); @@ -1097,24 +489,6 @@ int device_init(openair0_device_t *device, openair0_config_t *openair0_cfg) } else printf("[BRF] RX module enabled \n"); - // calibrate - -#if 0 - /* those calls fail for "Nuand bladeRF 2.0 (bladerf2)", so commented, - * but let's keep the code in case it's needed (for other boards, - * for anything, unfortunately we don't have other boards to test - * right now) - */ - if ((status=bladerf_calibrate_dc(brf->dev, BLADERF_DC_CAL_LPF_TUNING)) != 0 || - (status=bladerf_calibrate_dc(brf->dev, BLADERF_DC_CAL_TX_LPF)) != 0 || - (status=bladerf_calibrate_dc(brf->dev, BLADERF_DC_CAL_RX_LPF)) != 0 || - (status=bladerf_calibrate_dc(brf->dev, BLADERF_DC_CAL_RXVGA2)) != 0) { - fprintf(stderr, "[BRF] error calibrating\n"); - brf_error(status); - } else - printf("[BRF] calibration OK\n"); -#endif - /* set log to info, available log levels are: * - BLADERF_LOG_LEVEL_VERBOSE * - BLADERF_LOG_LEVEL_DEBUG @@ -1141,8 +515,6 @@ int device_init(openair0_device_t *device, openair0_config_t *openair0_cfg) device->openair0_cfg = openair0_cfg; device->priv = (void *)brf; - calibrate_rf(device); - // memcpy((void*)&device->openair0_cfg,(void*)&openair0_cfg[0],sizeof(openair0_config_t)); if ((status=bladerf_enable_module(brf->dev, BLADERF_MODULE_TX, false)) != 0) { @@ -1168,36 +540,4 @@ int brf_error(int status) exit(-1); return status; // or status error code } - - -/*! \brief Open BladeRF from serial port - * \param serial name of serial port on which to open BladeRF device - * \returns bladerf device structure - */ -struct bladerf * open_bladerf_from_serial(const char *serial) -{ - int status; - struct bladerf *dev; - struct bladerf_devinfo info; - /* Initialize all fields to "don't care" wildcard values. - * - * Immediately passing this to bladerf_open_with_devinfo() would cause - * libbladeRF to open any device on any available backend. */ - bladerf_init_devinfo(&info); - /* Specify the desired device's serial number, while leaving all other - * fields in the info structure wildcard values */ - strncpy(info.serial, serial, BLADERF_SERIAL_LENGTH - 1); - info.serial[BLADERF_SERIAL_LENGTH - 1] = '\0'; - status = bladerf_open_with_devinfo(&dev, &info); - - if (status == BLADERF_ERR_NODEV) { - printf("No devices available with serial=%s\n", serial); - return NULL; - } else if (status != 0) { - fprintf(stderr, "Failed to open device with serial=%s (%s)\n", serial, bladerf_strerror(status)); - return NULL; - } else { - return dev; - } -} /*@}*/ diff --git a/radio/BLADERF/bladerf_lib.h b/radio/BLADERF/bladerf_lib.h deleted file mode 100644 index a3ba44ee6c..0000000000 --- a/radio/BLADERF/bladerf_lib.h +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/** bladerf_lib.h - * - * Author: navid nikaein - */ - -#ifndef BLADERF_LIB_H -#define BLADERF_LIB_H - -#include - -#include "common_lib.h" - -/** @addtogroup _BLADERF_PHY_RF_INTERFACE_ - * @{ - */ - -/*! \brief BladeRF specific data structure */ -typedef struct { - - //! opaque BladeRF device struct. An empty ("") or NULL device identifier will result in the first encountered device being opened (using the first discovered backend) - struct bladerf *dev; - - //! Number of buffers - unsigned int num_buffers; - //! Buffer size - unsigned int buffer_size; - //! Number of transfers - unsigned int num_transfers; - //! RX timeout - unsigned int rx_timeout_ms; - //! TX timeout - unsigned int tx_timeout_ms; - //! Metadata for RX - struct bladerf_metadata meta_rx; - //!Metadata for TX - struct bladerf_metadata meta_tx; - //! Sample rate - unsigned int sample_rate; - //! time offset between transmiter timestamp and receiver timestamp; - double tdiff; - //! TX number of forward samples use brf_time_offset to get this value - int tx_forward_nsamps; //166 for 20Mhz - - - // -------------------------------- - // Debug and output control - // -------------------------------- - //! Number of underflows - int num_underflows; - //! Number of overflows - int num_overflows; - //! number of sequential errors - int num_seq_errors; - //! number of RX errors - int num_rx_errors; - //! Number of TX errors - int num_tx_errors; - - //! timestamp of current TX - uint64_t tx_current_ts; - //! timestamp of current RX - uint64_t rx_current_ts; - //! number of actual samples transmitted - uint64_t tx_actual_nsamps; - //! number of actual samples received - uint64_t rx_actual_nsamps; - //! number of TX samples - uint64_t tx_nsamps; - //! number of RX samples - uint64_t rx_nsamps; - //! number of TX count - uint64_t tx_count; - //! number of RX count - uint64_t rx_count; - //! timestamp of RX packet - openair0_timestamp_t rx_timestamp; - -} brf_state_t; -/* - * func prototypes - */ -/*! \brief BladeRF Init function (not used at the moment) - * \param device RF frontend parameters set by application - */ -int trx_brf_init(openair0_device_t *device); - -/*! \brief get current timestamp - *\param device the hardware to use - *\param module the bladeRf module - */ -openair0_timestamp_t trx_get_timestamp(openair0_device_t *device, bladerf_module module); - -/*! \brief bladeRF error report - * \param status - * \returns 0 on success - */ -int brf_error(int status); - -/*@}*/ - -#endif /* BLADERF_LIB_H */ From 4fdcb11edda9efcd08fe527933a421d4cdeef8f4 Mon Sep 17 00:00:00 2001 From: Brice Robert Date: Wed, 4 Feb 2026 10:25:19 +0100 Subject: [PATCH 07/15] BladeRF: Use global constant for used sampling format --- radio/BLADERF/bladerf_lib.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/radio/BLADERF/bladerf_lib.c b/radio/BLADERF/bladerf_lib.c index 5bb2f069dc..affaef3b61 100644 --- a/radio/BLADERF/bladerf_lib.c +++ b/radio/BLADERF/bladerf_lib.c @@ -85,6 +85,8 @@ int brf_error(int status); * @{ */ +const bladerf_format format = BLADERF_FORMAT_SC16_Q11_META; + /*! \brief Start BladeRF * \param device the hardware to use * \returns 0 on success @@ -98,7 +100,7 @@ int trx_brf_start(openair0_device_t *device) if ((status = bladerf_sync_config(brf->dev, BLADERF_MODULE_TX, - BLADERF_FORMAT_SC16_Q11_META, + format, brf->num_buffers, brf->buffer_size, brf->num_transfers, @@ -108,7 +110,7 @@ int trx_brf_start(openair0_device_t *device) } if ((status = bladerf_sync_config(brf->dev, BLADERF_MODULE_RX, - BLADERF_FORMAT_SC16_Q11_META, + format, brf->num_buffers, brf->buffer_size, brf->num_transfers, From f14aa8283c2bfde2058dfe986f7f3b8083b3e437 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 4 Feb 2026 10:25:40 +0100 Subject: [PATCH 08/15] Active BladeRF on startup only, introduce BLADERF_CHECK Don't enable radios twice, and only do it on device startup. Simplify that function by using a new BLADERF_CHECK macro that checks return codes and that will be reused in the following commits. --- radio/BLADERF/bladerf_lib.c | 106 +++++++++++++----------------------- 1 file changed, 39 insertions(+), 67 deletions(-) diff --git a/radio/BLADERF/bladerf_lib.c b/radio/BLADERF/bladerf_lib.c index affaef3b61..8326d83084 100644 --- a/radio/BLADERF/bladerf_lib.c +++ b/radio/BLADERF/bladerf_lib.c @@ -85,55 +85,60 @@ int brf_error(int status); * @{ */ +#define BLADERF_CHECK(COND, FMT, ...) \ + if (COND) { \ + LOG_I(HW, FMT "\n" __VA_OPT__(, ) __VA_ARGS__); \ + } else { \ + LOG_E(HW, "Failed: " FMT ": %s\n" __VA_OPT__(, ) __VA_ARGS__, bladerf_strerror(status)); \ + return -1; \ + } + const bladerf_format format = BLADERF_FORMAT_SC16_Q11_META; /*! \brief Start BladeRF * \param device the hardware to use * \returns 0 on success */ -int trx_brf_start(openair0_device_t *device) +static int trx_brf_start(openair0_device_t *device) { - brf_state_t *brf = (brf_state_t*)device->priv; - int status; + brf_state_t *brf = device->priv; + int status; - brf->meta_tx.flags = 0; + brf->meta_tx.flags = 0; - if ((status = bladerf_sync_config(brf->dev, - BLADERF_MODULE_TX, - format, - brf->num_buffers, - brf->buffer_size, - brf->num_transfers, - 100/*brf->tx_timeout_ms*/)) != 0 ) { - fprintf(stderr,"Failed to configure TX sync interface: %s\n", bladerf_strerror(status)); - abort(); - } - if ((status = bladerf_sync_config(brf->dev, - BLADERF_MODULE_RX, - format, - brf->num_buffers, - brf->buffer_size, - brf->num_transfers, - 100/*brf->rx_timeout_ms*/)) != 0 ) { - fprintf(stderr,"Failed to configure RX sync interface: %s\n", bladerf_strerror(status)); - abort(); - } - if ((status=bladerf_enable_module(brf->dev, BLADERF_MODULE_TX, true)) != 0) { - fprintf(stderr,"Failed to enable TX module: %s\n", bladerf_strerror(status)); - abort(); - } - if ((status=bladerf_enable_module(brf->dev, BLADERF_MODULE_RX, true)) != 0) { - fprintf(stderr,"Failed to enable RX module: %s\n", bladerf_strerror(status)); - abort(); - } + /* Configure the device's TX module for use with the sync interface. + * SC16 Q11 samples *with* metadata are used. */ + status = bladerf_sync_config(brf->dev, BLADERF_MODULE_TX, format, + brf->num_buffers, brf->buffer_size, brf->num_transfers, brf->tx_timeout_ms); + BLADERF_CHECK(status == 0, + "Set TX sync interface num_buffers %u, buffer_size %u, num_transfer %u, tx_timeout_ms %u", + brf->num_buffers, brf->buffer_size, brf->num_transfers, brf->tx_timeout_ms); - return 0; + /* Configure the device's RX module for use with the sync interface. + * SC16 Q11 samples *with* metadata are used. */ + status = bladerf_sync_config(brf->dev, BLADERF_MODULE_RX, format, + brf->num_buffers, brf->buffer_size, brf->num_transfers, brf->rx_timeout_ms); + BLADERF_CHECK(status == 0, + "Set RX sync interface num_buffers %u, buffer_size %u, num_transfer %u, rx_timeout_ms %u", + brf->num_buffers, brf->buffer_size, brf->num_transfers, brf->rx_timeout_ms); + + /* We must always enable the TX module after calling bladerf_sync_config(), and + * before attempting to TX samples via bladerf_sync_tx(). */ + status = bladerf_enable_module(brf->dev, BLADERF_MODULE_TX, true); + BLADERF_CHECK(status == 0, "Enable TX module"); + + /* We must always enable the RX module after calling bladerf_sync_config(), and + * before attempting to RX samples via bladerf_sync_rx(). */ + status = bladerf_enable_module(brf->dev, BLADERF_MODULE_RX, true); + BLADERF_CHECK(status == 0, "Enable RX module"); + + return 0; } /*! \brief Called to send samples to the BladeRF RF target \param device pointer to the device structure specific to the RF hardware target - \param timestamp The timestamp at whicch the first sample MUST be sent + \param timestamp The timestamp at which the first sample MUST be sent \param buff Buffer which holds the samples \param nsamps number of samples to be sent \param cc index of the component carrier @@ -458,39 +463,6 @@ int device_init(openair0_device_t *device, openair0_config_t *openair0_cfg) printf("[BRF] set the TX gain to %d\n", (int)openair0_cfg->tx_gain[0]); - /* Configure the device's TX module for use with the sync interface. - * SC16 Q11 samples *with* metadata are used. */ - if ((status=bladerf_sync_config(brf->dev, BLADERF_MODULE_TX,BLADERF_FORMAT_SC16_Q11_META,brf->num_buffers,brf->buffer_size,brf->num_transfers,brf->tx_timeout_ms)) != 0 ) { - fprintf(stderr,"Failed to configure TX sync interface: %s\n", bladerf_strerror(status)); - brf_error(status); - } else - printf("[BRF] configured TX sync interface \n"); - - /* Configure the device's RX module for use with the sync interface. - * SC16 Q11 samples *with* metadata are used. */ - if ((status=bladerf_sync_config(brf->dev, BLADERF_MODULE_RX, BLADERF_FORMAT_SC16_Q11_META,brf->num_buffers,brf->buffer_size,brf->num_transfers,brf->rx_timeout_ms)) != 0 ) { - fprintf(stderr,"Failed to configure RX sync interface: %s\n", bladerf_strerror(status)); - brf_error(status); - } else - printf("[BRF] configured Rx sync interface \n"); - - - /* We must always enable the TX module after calling bladerf_sync_config(), and - * before attempting to TX samples via bladerf_sync_tx(). */ - if ((status=bladerf_enable_module(brf->dev, BLADERF_MODULE_TX, true)) != 0) { - fprintf(stderr,"Failed to enable TX module: %s\n", bladerf_strerror(status)); - brf_error(status); - } else - printf("[BRF] TX module enabled \n"); - - /* We must always enable the RX module after calling bladerf_sync_config(), and - * before attempting to RX samples via bladerf_sync_rx(). */ - if ((status=bladerf_enable_module(brf->dev, BLADERF_MODULE_RX, true)) != 0) { - fprintf(stderr,"Failed to enable RX module: %s\n", bladerf_strerror(status)); - brf_error(status); - } else - printf("[BRF] RX module enabled \n"); - /* set log to info, available log levels are: * - BLADERF_LOG_LEVEL_VERBOSE * - BLADERF_LOG_LEVEL_DEBUG From 792e1ed7d929d74a773ec3b3feefa915d9fb6899 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 4 Feb 2026 10:25:59 +0100 Subject: [PATCH 09/15] Rewrite BladeRF's device_init() - Add more sampling rates to support, e.g., 40MHz in 5G - Allocate memory only at end to avoid memory leaks in case of failure - Group recurring configuration functionality in configure_channel() to reduced code duplication and uniform output - Read maximum TX gain to set maximum automatically, and analogous to USRP radio lib - Check if BladeRF config (buffer size, num transfers, ...) fulfills requirements as specified in documentation [1] - Set BladeRF logging early to see BladeRF output [1] https://www.nuand.com/bladeRF-doc/libbladeRF/v2.6.0/group___f_n___s_t_r_e_a_m_i_n_g___a_s_y_n_c.html#ga72752f2a047b95544e7686596a409abd Co-authored-by: Brice Robert Closes: #845 --- radio/BLADERF/bladerf_lib.c | 336 ++++++++++++++++++++---------------- 1 file changed, 188 insertions(+), 148 deletions(-) diff --git a/radio/BLADERF/bladerf_lib.c b/radio/BLADERF/bladerf_lib.c index 8326d83084..e3effac03f 100644 --- a/radio/BLADERF/bladerf_lib.c +++ b/radio/BLADERF/bladerf_lib.c @@ -95,6 +95,23 @@ int brf_error(int status); const bladerf_format format = BLADERF_FORMAT_SC16_Q11_META; +static const char *ch_dir(bladerf_channel ch) +{ + switch (ch) { + case BLADERF_CHANNEL_RX(0): + return "RX0"; + case BLADERF_CHANNEL_RX(1): + return "RX1"; + case BLADERF_CHANNEL_TX(0): + return "TX0"; + case BLADERF_CHANNEL_TX(1): + return "TX1"; + default: + return "unknown"; + } + return "unknown"; +} + /*! \brief Start BladeRF * \param device the hardware to use * \returns 0 on success @@ -333,6 +350,40 @@ int trx_brf_write_init(openair0_device_t *device) return 0; } +typedef struct channel_config { + bladerf_channel channel; + unsigned int frequency; + unsigned int sample_rate; + unsigned int bandwidth; + int gain; +} channel_config_t; + + +static int configure_channel(struct bladerf *dev, channel_config_t *c) +{ + int status; + unsigned int actual_value = 0; + const char *dir = ch_dir(c->channel); + + status = bladerf_set_frequency(dev, c->channel, c->frequency); + BLADERF_CHECK(status == 0, "Set %s frequency %u", dir, c->frequency); + + status = bladerf_set_sample_rate(dev, c->channel, c->sample_rate, &actual_value); + BLADERF_CHECK(status == 0, "Set %s sample rate %u (is %u)", dir, c->sample_rate, actual_value); + + status = bladerf_set_bandwidth(dev, c->channel, c->bandwidth, &actual_value); + BLADERF_CHECK(status == 0, "Set %s bandwidth %u (is %u)", dir, c->bandwidth, actual_value); + + status = bladerf_set_gain(dev, c->channel, c->gain); + BLADERF_CHECK(status == 0, "Set %s gain %u", dir, c->gain); + + bladerf_gain g; + status = bladerf_get_gain(dev, c->channel, &g); + BLADERF_CHECK(status == 0, "Get %s gain: %u", dir, g); + + return 0; +} + /*! \brief Initialize Openair BLADERF target. It returns 0 if OK * \param device the hardware to use * \param openair0_cfg RF frontend parameters set by application @@ -340,167 +391,156 @@ int trx_brf_write_init(openair0_device_t *device) */ int device_init(openair0_device_t *device, openair0_config_t *openair0_cfg) { - int status; - brf_state_t *brf = (brf_state_t*)malloc(sizeof(brf_state_t)); - memset(brf, 0, sizeof(brf_state_t)); - /* device specific */ - //openair0_cfg->txlaunch_wait = 1;//manage when TX processing is triggered - //openair0_cfg->txlaunch_wait_slotcount = 1; //manage when TX processing is triggered + int status; + brf_state_t brf = {0}; + + switch ((long) openair0_cfg->sample_rate) { + case 46080000: + openair0_cfg->samples_per_packet = 8192; + openair0_cfg->tx_sample_advance = 0; + brf.num_buffers = 128; + brf.num_transfers = 32; + brf.rx_timeout_ms = 2000; + break; - // init required params - switch ((int)openair0_cfg->sample_rate) { case 30720000: - openair0_cfg->samples_per_packet = 2048; - openair0_cfg->tx_sample_advance = 0; - break; + openair0_cfg->samples_per_packet = 4096; + openair0_cfg->tx_sample_advance = 0; + brf.num_buffers = 128; + brf.num_transfers = 32; + brf.rx_timeout_ms = 2000; + break; + + case 23040000: + openair0_cfg->samples_per_packet = 2048; + openair0_cfg->tx_sample_advance = 0; + brf.num_buffers = 64; + brf.num_transfers = 16; + brf.rx_timeout_ms = 2000; + break; + case 15360000: - openair0_cfg->samples_per_packet = 2048; - openair0_cfg->tx_sample_advance = 0; - break; + openair0_cfg->samples_per_packet = 2048; + openair0_cfg->tx_sample_advance = 0; + + brf.num_buffers = 64; + brf.num_transfers = 16; + brf.rx_timeout_ms = 2000; + break; + case 11520000: + openair0_cfg->samples_per_packet = 2048; + openair0_cfg->tx_sample_advance = 0; + brf.num_buffers = 64; + brf.num_transfers = 16; + brf.rx_timeout_ms = 2000; + break; + case 7680000: - openair0_cfg->samples_per_packet = 1024; - openair0_cfg->tx_sample_advance = 0; - break; + openair0_cfg->samples_per_packet = 1024; + openair0_cfg->tx_sample_advance = 0; + brf.num_buffers = 32; + brf.num_transfers = 16; + brf.rx_timeout_ms = 2000; + break; + case 1920000: - openair0_cfg->samples_per_packet = 256; - openair0_cfg->tx_sample_advance = 50; - break; + openair0_cfg->samples_per_packet = 256; + openair0_cfg->tx_sample_advance = 50; + brf.num_buffers = 128; + brf.num_transfers = 16; + brf.rx_timeout_ms = 2000; + break; + default: - printf("Error: unknown sampling rate %f\n",openair0_cfg->sample_rate); - exit(-1); - break; + LOG_E(HW, "Error: unknown sampling rate %f\n", openair0_cfg->sample_rate); + return -1; + break; + } + + brf.tx_timeout_ms = 2000; + brf.buffer_size = (unsigned int)openair0_cfg->samples_per_packet; + brf.sample_rate = (unsigned int)openair0_cfg->sample_rate; + + float rxterm = brf.num_transfers * brf.buffer_size * 1000.0 / brf.rx_timeout_ms; + float txterm = brf.num_transfers * brf.buffer_size * 1000.0 / brf.tx_timeout_ms; + LOG_I(HW, + "sample rate %d trnsfers %d timeout rx %d tx %d buffer size %d (rx %f, tx %f)\n", + brf.sample_rate, + brf.num_transfers, + brf.rx_timeout_ms, + brf.tx_timeout_ms, + brf.buffer_size, + rxterm, + txterm); + DevAssert(brf.sample_rate > txterm * 1.25); // see doc on async interface + DevAssert(brf.sample_rate > rxterm * 1.25); + + memset(&brf.meta_rx, 0, sizeof(brf.meta_rx)); + memset(&brf.meta_tx, 0, sizeof(brf.meta_tx)); + + // set this to BLADERF_LOG_LEVEL_VERBOSE for more detailed BladeRF info + bladerf_log_set_verbosity(BLADERF_LOG_LEVEL_INFO); + + status = bladerf_open(&brf.dev, openair0_cfg->sdr_addrs); + BLADERF_CHECK(status == 0, "Init BladeRF device '%s'", openair0_cfg->sdr_addrs); + + if (bladerf_device_speed(brf.dev) != BLADERF_DEVICE_SPEED_SUPER) { + LOG_E(HW, "Device does not operate at max speed, change the USB port\n"); + return -1; } - // The number of buffers to use in the underlying data stream - brf->num_buffers = 128; - // the size of the underlying stream buffers, in samples - brf->buffer_size = (unsigned int) openair0_cfg->samples_per_packet;//*sizeof(int32_t); // buffer size = 4096 for sample_len of 1024 - brf->num_transfers = 16; - brf->rx_timeout_ms = 0; - brf->tx_timeout_ms = 0; - brf->sample_rate=(unsigned int)openair0_cfg->sample_rate; + /** [Forcing Tuning Mode to FPGA] */ + const bladerf_tuning_mode tMode = BLADERF_TUNING_MODE_FPGA; + status = bladerf_set_tuning_mode(brf.dev, tMode); + BLADERF_CHECK(status == 0, "Set tuning mode FPGA"); - memset(&brf->meta_rx, 0, sizeof(brf->meta_rx)); - memset(&brf->meta_tx, 0, sizeof(brf->meta_tx)); + status = bladerf_set_gain_mode(brf.dev, BLADERF_CHANNEL_RX(0), BLADERF_GAIN_MGC); + BLADERF_CHECK(status == 0, "Disable AGC"); - printf("\n[BRF] sampling_rate %u, num_buffers %u, buffer_size %u, num transfer %u, timeout_ms (rx %u, tx %u)\n", - brf->sample_rate, brf->num_buffers, brf->buffer_size,brf->num_transfers, brf->rx_timeout_ms, brf->tx_timeout_ms); + channel_config_t rx_chan = { + .channel = BLADERF_CHANNEL_RX(0), + .frequency = openair0_cfg->rx_freq[0], + .sample_rate = openair0_cfg->sample_rate, + .bandwidth = openair0_cfg->rx_bw, + .gain = openair0_cfg->rx_gain[0], + }; + configure_channel(brf.dev, &rx_chan); - if ((status=bladerf_open(&brf->dev, "")) != 0 ) { - fprintf(stderr,"Failed to open brf device: %s\n",bladerf_strerror(status)); - brf_error(status); - } - printf("[BRF] init dev %p\n", brf->dev); - switch(bladerf_device_speed(brf->dev)) { - case BLADERF_DEVICE_SPEED_SUPER: - printf("[BRF] Device operates at max speed\n"); - break; - default: - printf("[BRF] Device does not operates at max speed, change the USB port\n"); - brf_error(BLADERF_ERR_UNSUPPORTED); - } - // RX - // Example of CLI output: RX Frequency: 2539999999Hz + // This is a hack. The USRP library currently does max_gain-tx_gain (tx_gain + // is the attenuation, so completely illogical), but let's keep what users + // would expect by doing the same. Existing configs can then be reused. + // Note also that the doc says that get_gain_range() should be called after + // setting the frequency, but the gain should normally come from outside, so + // be set by user and independent of the exact frequency. + const struct bladerf_range *g = NULL; + status = bladerf_get_gain_range(brf.dev, BLADERF_CHANNEL_TX(0), &g); + BLADERF_CHECK(status == 0 && g != NULL, "Get TX0 gain range"); + channel_config_t tx_chan = { + .channel = BLADERF_CHANNEL_TX(0), + .frequency = openair0_cfg->tx_freq[0], + .sample_rate = openair0_cfg->sample_rate, + .bandwidth = openair0_cfg->tx_bw, + .gain = g->max - openair0_cfg->tx_gain[0], // see comment above + }; + configure_channel(brf.dev, &tx_chan); + LOG_I(HW, "BLADERF: Initializing device done\n"); + device->type = BLADERF_DEV; + device->trx_start_func = trx_brf_start; + device->trx_end_func = trx_brf_end; + device->trx_read_func = trx_brf_read; + device->trx_write_func = trx_brf_write; + device->trx_get_stats_func = trx_brf_get_stats; + device->trx_reset_stats_func = trx_brf_reset_stats; + device->trx_stop_func = trx_brf_stop; + device->trx_set_freq_func = trx_brf_set_freq; + device->trx_set_gains_func = trx_brf_set_gains; + device->trx_write_init = trx_brf_write_init; + device->openair0_cfg = openair0_cfg; + device->priv = malloc_or_fail(sizeof(brf_state_t)); + *(brf_state_t *)device->priv = brf; - if ((status=bladerf_set_gain_mode(brf->dev, BLADERF_MODULE_RX, BLADERF_GAIN_MGC))) { - fprintf(stderr, "[BRF] Failed to disable AGC\n"); - brf_error(status); - } - - if ((status=bladerf_set_frequency(brf->dev, BLADERF_MODULE_RX, (unsigned int) openair0_cfg->rx_freq[0])) != 0) { - fprintf(stderr,"Failed to set RX frequency: %s\n",bladerf_strerror(status)); - brf_error(status); - } else - printf("[BRF] set RX frequency to %u\n",(unsigned int)openair0_cfg->rx_freq[0]); - - - - unsigned int actual_value=0; - if ((status=bladerf_set_sample_rate(brf->dev, BLADERF_MODULE_RX, (unsigned int) openair0_cfg->sample_rate, &actual_value)) != 0) { - fprintf(stderr,"Failed to set RX sample rate: %s\n", bladerf_strerror(status)); - brf_error(status); - } else - printf("[BRF] set RX sample rate to %u, %u\n", (unsigned int) openair0_cfg->sample_rate, actual_value); - - - if ((status=bladerf_set_bandwidth(brf->dev, BLADERF_MODULE_RX, (unsigned int) openair0_cfg->rx_bw*2, &actual_value)) != 0) { - fprintf(stderr,"Failed to set RX bandwidth: %s\n", bladerf_strerror(status)); - brf_error(status); - } else - printf("[BRF] set RX bandwidth to %u, %u\n",(unsigned int)openair0_cfg->rx_bw*2, actual_value); - - if ((status=bladerf_set_gain(brf->dev, BLADERF_MODULE_RX, (int) openair0_cfg->rx_gain[0]-openair0_cfg[0].rx_gain_offset[0])) != 0) { - fprintf(stderr,"Failed to set RX gain: %s\n",bladerf_strerror(status)); - brf_error(status); - } else - printf("[BRF] set RX gain to %d (%d)\n",(int)(openair0_cfg->rx_gain[0]-openair0_cfg[0].rx_gain_offset[0]),(int)openair0_cfg[0].rx_gain_offset[0]); - - // TX - - if ((status=bladerf_set_frequency(brf->dev, BLADERF_MODULE_TX, (unsigned int) openair0_cfg->tx_freq[0])) != 0) { - fprintf(stderr,"Failed to set TX frequency: %s\n",bladerf_strerror(status)); - brf_error(status); - } else - printf("[BRF] set TX Frequency to %u\n", (unsigned int) openair0_cfg->tx_freq[0]); - - if ((status=bladerf_set_sample_rate(brf->dev, BLADERF_MODULE_TX, (unsigned int) openair0_cfg->sample_rate, NULL)) != 0) { - fprintf(stderr,"Failed to set TX sample rate: %s\n", bladerf_strerror(status)); - brf_error(status); - } else - printf("[BRF] set TX sampling rate to %u \n", (unsigned int) openair0_cfg->sample_rate); - - if ((status=bladerf_set_bandwidth(brf->dev, BLADERF_MODULE_TX,(unsigned int)openair0_cfg->tx_bw*2, NULL)) != 0) { - fprintf(stderr, "Failed to set TX bandwidth: %s\n", bladerf_strerror(status)); - brf_error(status); - } else - printf("[BRF] set TX bandwidth to %u \n", (unsigned int) openair0_cfg->tx_bw*2); - - if ((status=bladerf_set_gain(brf->dev, BLADERF_MODULE_TX, (int) openair0_cfg->tx_gain[0])) != 0) { - fprintf(stderr,"Failed to set TX gain: %s\n",bladerf_strerror(status)); - brf_error(status); - } else - printf("[BRF] set the TX gain to %d\n", (int)openair0_cfg->tx_gain[0]); - - - /* set log to info, available log levels are: - * - BLADERF_LOG_LEVEL_VERBOSE - * - BLADERF_LOG_LEVEL_DEBUG - * - BLADERF_LOG_LEVEL_INFO - * - BLADERF_LOG_LEVEL_WARNING - * - BLADERF_LOG_LEVEL_ERROR - * - BLADERF_LOG_LEVEL_CRITICAL - * - BLADERF_LOG_LEVEL_SILENT - */ - bladerf_log_set_verbosity(BLADERF_LOG_LEVEL_INFO); - - printf("BLADERF: Initializing openair0_device_t\n"); - device->type = BLADERF_DEV; - device->trx_start_func = trx_brf_start; - device->trx_end_func = trx_brf_end; - device->trx_read_func = trx_brf_read; - device->trx_write_func = trx_brf_write; - device->trx_get_stats_func = trx_brf_get_stats; - device->trx_reset_stats_func = trx_brf_reset_stats; - device->trx_stop_func = trx_brf_stop; - device->trx_set_freq_func = trx_brf_set_freq; - device->trx_set_gains_func = trx_brf_set_gains; - device->trx_write_init = trx_brf_write_init; - device->openair0_cfg = openair0_cfg; - device->priv = (void *)brf; - - // memcpy((void*)&device->openair0_cfg,(void*)&openair0_cfg[0],sizeof(openair0_config_t)); - - if ((status=bladerf_enable_module(brf->dev, BLADERF_MODULE_TX, false)) != 0) { - fprintf(stderr,"Failed to enable TX module: %s\n", bladerf_strerror(status)); - abort(); - } - if ((status=bladerf_enable_module(brf->dev, BLADERF_MODULE_RX, false)) != 0) { - fprintf(stderr,"Failed to enable RX module: %s\n", bladerf_strerror(status)); - abort(); - } - - return 0; + return 0; } From 80b5d4ef228316196078e424b80d4d5f461536fd Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 4 Feb 2026 10:30:54 +0100 Subject: [PATCH 10/15] Make functions static, reformat, use logging module This commit does not introduce a functional change. --- radio/BLADERF/bladerf_lib.c | 221 +++++++++++++++--------------------- 1 file changed, 93 insertions(+), 128 deletions(-) diff --git a/radio/BLADERF/bladerf_lib.c b/radio/BLADERF/bladerf_lib.c index e3effac03f..437aef4c23 100644 --- a/radio/BLADERF/bladerf_lib.c +++ b/radio/BLADERF/bladerf_lib.c @@ -79,8 +79,6 @@ typedef struct { uint64_t rx_count; } brf_state_t; -int brf_error(int status); - /** @addtogroup _BLADERF_PHY_RF_INTERFACE_ * @{ */ @@ -125,7 +123,7 @@ static int trx_brf_start(openair0_device_t *device) /* Configure the device's TX module for use with the sync interface. * SC16 Q11 samples *with* metadata are used. */ - status = bladerf_sync_config(brf->dev, BLADERF_MODULE_TX, format, + status = bladerf_sync_config(brf->dev, BLADERF_CHANNEL_TX(0), format, brf->num_buffers, brf->buffer_size, brf->num_transfers, brf->tx_timeout_ms); BLADERF_CHECK(status == 0, "Set TX sync interface num_buffers %u, buffer_size %u, num_transfer %u, tx_timeout_ms %u", @@ -133,7 +131,7 @@ static int trx_brf_start(openair0_device_t *device) /* Configure the device's RX module for use with the sync interface. * SC16 Q11 samples *with* metadata are used. */ - status = bladerf_sync_config(brf->dev, BLADERF_MODULE_RX, format, + status = bladerf_sync_config(brf->dev, BLADERF_CHANNEL_RX(0), format, brf->num_buffers, brf->buffer_size, brf->num_transfers, brf->rx_timeout_ms); BLADERF_CHECK(status == 0, "Set RX sync interface num_buffers %u, buffer_size %u, num_transfer %u, rx_timeout_ms %u", @@ -141,14 +139,17 @@ static int trx_brf_start(openair0_device_t *device) /* We must always enable the TX module after calling bladerf_sync_config(), and * before attempting to TX samples via bladerf_sync_tx(). */ - status = bladerf_enable_module(brf->dev, BLADERF_MODULE_TX, true); - BLADERF_CHECK(status == 0, "Enable TX module"); + status = bladerf_enable_module(brf->dev, BLADERF_CHANNEL_TX(0), true); + BLADERF_CHECK(status == 0, "Enable TX0 module"); /* We must always enable the RX module after calling bladerf_sync_config(), and * before attempting to RX samples via bladerf_sync_rx(). */ - status = bladerf_enable_module(brf->dev, BLADERF_MODULE_RX, true); + status = bladerf_enable_module(brf->dev, BLADERF_CHANNEL_RX(0), true); BLADERF_CHECK(status == 0, "Enable RX module"); + // in case it was set to verbosity before, disable now because otherwise the + // terminal will be flooded + bladerf_log_set_verbosity(BLADERF_LOG_LEVEL_INFO); return 0; } @@ -164,46 +165,37 @@ static int trx_brf_start(openair0_device_t *device) */ static int trx_brf_write(openair0_device_t *device, openair0_timestamp_t ptimestamp, void **buff, int nsamps, int cc, int flags) { - int status; - brf_state_t *brf = (brf_state_t*)device->priv; - /* BRF has only 1 rx/tx chaine : is it correct? */ - int16_t *samples = (int16_t*)buff[0]; - ptimestamp -= device->openair0_cfg->command_line_sample_advance - device->openair0_cfg->tx_sample_advance; - //memset(&brf->meta_tx, 0, sizeof(brf->meta_tx)); - // When BLADERF_META_FLAG_TX_NOW is used the timestamp is not used, so one can't schedule a tx - if (brf->meta_tx.flags == 0 ) - brf->meta_tx.flags = (BLADERF_META_FLAG_TX_BURST_START);// | BLADERF_META_FLAG_TX_BURST_END);// | BLADERF_META_FLAG_TX_NOW); + brf_state_t *brf = device->priv; + /* BRF has only 1 rx/tx chaine : is it correct? TODO: now, handle also two! */ + int16_t *samples = (int16_t *)buff[0]; + ptimestamp -= device->openair0_cfg->command_line_sample_advance - device->openair0_cfg->tx_sample_advance; - brf->meta_tx.timestamp= (uint64_t) (ptimestamp); - status = bladerf_sync_tx(brf->dev, samples, (unsigned int) nsamps, &brf->meta_tx, 2*brf->tx_timeout_ms); + // When BLADERF_META_FLAG_TX_NOW is used the timestamp is not used, so one can't schedule a tx + if (brf->meta_tx.flags == 0) + brf->meta_tx.flags = BLADERF_META_FLAG_TX_BURST_START; + brf->meta_tx.timestamp = (uint64_t)(ptimestamp); - if (brf->meta_tx.flags == BLADERF_META_FLAG_TX_BURST_START) - brf->meta_tx.flags = BLADERF_META_FLAG_TX_UPDATE_TIMESTAMP; + int status = bladerf_sync_tx(brf->dev, samples, nsamps, &brf->meta_tx, 2 * brf->tx_timeout_ms); + if (status == BLADERF_ERR_TIME_PAST) { + brf->num_tx_errors++; + LOG_W(HW, "Timestamp error: Requested timestamp %ld is in the past.\n", ptimestamp); + } else if (status != 0) { + brf->num_tx_errors++; + LOG_W(HW, "Error during TX: %s\n", bladerf_strerror(status)); + } + if (brf->meta_tx.flags == BLADERF_META_FLAG_TX_BURST_START) + brf->meta_tx.flags = BLADERF_META_FLAG_TX_UPDATE_TIMESTAMP; - if (status != 0) { - //fprintf(stderr,"Failed to TX sample: %s\n", bladerf_strerror(status)); - brf->num_tx_errors++; - brf_error(status); - } else if (brf->meta_tx.status & BLADERF_META_STATUS_UNDERRUN) { - /* libbladeRF does not report this status. It is here for future use. */ - fprintf(stderr, "TX Underrun detected. %u valid samples were read.\n", brf->meta_tx.actual_count); - brf->num_underflows++; - } - //printf("Provided TX timestampe %u, meta timestame %u\n", ptimestamp,brf->meta_tx.timestamp); + brf->tx_current_ts = brf->meta_tx.timestamp; + brf->tx_actual_nsamps += brf->meta_tx.actual_count; + brf->tx_nsamps += nsamps; + brf->tx_count++; - // printf("tx status %d \n",brf->meta_tx.status); - brf->tx_current_ts=brf->meta_tx.timestamp; - brf->tx_actual_nsamps+=brf->meta_tx.actual_count; - brf->tx_nsamps+=nsamps; - brf->tx_count++; - - - return nsamps; //brf->meta_tx.actual_count; + return nsamps; // brf->meta_tx.actual_count; } - /*! \brief Receive samples from hardware. * Read \ref nsamps samples from each channel to buffers. buff[0] is the array for * the first channel. *ptimestamp is the time at which the first sample @@ -217,63 +209,56 @@ static int trx_brf_write(openair0_device_t *device, openair0_timestamp_t ptimest */ static int trx_brf_read(openair0_device_t *device, openair0_timestamp_t *ptimestamp, void **buff, int nsamps, int cc) { - int status=0; - brf_state_t *brf = (brf_state_t*)device->priv; + brf_state_t *brf = device->priv; - // BRF has only one rx/tx chain - int16_t *samples = (int16_t*)buff[0]; + // BRF has only one rx/tx chain + int16_t *samples = (int16_t *)buff[0]; - brf->meta_rx.actual_count = 0; - brf->meta_rx.flags = BLADERF_META_FLAG_RX_NOW; - status = bladerf_sync_rx(brf->dev, samples, (unsigned int) nsamps, &brf->meta_rx, 2*brf->rx_timeout_ms); + brf->meta_rx.actual_count = 0; + brf->meta_rx.flags = BLADERF_META_FLAG_RX_NOW; + int status = bladerf_sync_rx(brf->dev, samples, (unsigned int)nsamps, &brf->meta_rx, 2 * brf->rx_timeout_ms); - // printf("Current RX timestampe %u, nsamps %u, actual %u, cc %d\n", brf->meta_rx.timestamp, nsamps, brf->meta_rx.actual_count, cc); + if (status != 0) { + LOG_E(HW, "RX failed: %s\n", bladerf_strerror(status)); + brf->num_rx_errors++; + } else if (brf->meta_rx.status & BLADERF_META_STATUS_OVERRUN) { + brf->num_overflows++; + LOG_W(HW, + "%d RX overrun is detected. timestamp %ld. Requested %u but got %u samples\n", + brf->num_overflows, + brf->meta_rx.timestamp, + brf->meta_rx.actual_count, + nsamps); + } - if (status != 0) { - fprintf(stderr, "RX failed: %s\n", bladerf_strerror(status)); - // printf("RX failed: %s\n", bladerf_strerror(status)); - brf->num_rx_errors++; - } else if ( brf->meta_rx.status & BLADERF_META_STATUS_OVERRUN) { - brf->num_overflows++; - printf("RX overrun (%d) is detected. t=" "%" PRIu64 "Got %u samples. nsymps %d\n", - brf->num_overflows,brf->meta_rx.timestamp, brf->meta_rx.actual_count, nsamps); - } + if (brf->meta_rx.actual_count != nsamps) { + LOG_E(HW, "RX bad samples count, wanted %d, got %d\n", nsamps, brf->meta_rx.actual_count); + } - if (brf->meta_rx.actual_count != nsamps) { - printf("RX bad samples count, wanted %d, got %d\n", nsamps, brf->meta_rx.actual_count); - } + brf->rx_current_ts = brf->meta_rx.timestamp; + brf->rx_actual_nsamps += brf->meta_rx.actual_count; + brf->rx_nsamps += nsamps; + brf->rx_count++; - //printf("Current RX timestampe %u\n", brf->meta_rx.timestamp); - //printf("[BRF] (buff %p) ts=0x%"PRIu64" %s\n",samples, brf->meta_rx.timestamp,bladerf_strerror(status)); - brf->rx_current_ts=brf->meta_rx.timestamp; - brf->rx_actual_nsamps+=brf->meta_rx.actual_count; - brf->rx_nsamps+=nsamps; - brf->rx_count++; - - - *ptimestamp = brf->meta_rx.timestamp; - - return nsamps; //brf->meta_rx.actual_count; + *ptimestamp = brf->meta_rx.timestamp; + return nsamps; // brf->meta_rx.actual_count; } - /*! \brief Terminate operation of the BladeRF transceiver -- free all associated resources * \param device the hardware to use */ -void trx_brf_end(openair0_device_t *device) +static void trx_brf_end(openair0_device_t *device) { - int status; - brf_state_t *brf = (brf_state_t*)device->priv; - // Disable RX module, shutting down our underlying RX stream - if ((status=bladerf_enable_module(brf->dev, BLADERF_MODULE_RX, false)) != 0) { - fprintf(stderr, "Failed to disable RX module: %s\n", bladerf_strerror(status)); - } - if ((status=bladerf_enable_module(brf->dev, BLADERF_MODULE_TX, false)) != 0) { - fprintf(stderr, "Failed to disable TX module: %s\n", bladerf_strerror(status)); - } - bladerf_close(brf->dev); - exit(1); + brf_state_t *brf = device->priv; + // Disable RX module, shutting down our underlying RX stream + + int status; + if ((status = bladerf_enable_module(brf->dev, BLADERF_CHANNEL_RX(0), false)) != 0) + LOG_E(HW, "Failed: Disable RX module: %s\n", bladerf_strerror(status)); + if ((status = bladerf_enable_module(brf->dev, BLADERF_CHANNEL_TX(0), false)) != 0) + LOG_E(HW, "Failed: Disable TX module: %s\n", bladerf_strerror(status)); + bladerf_close(brf->dev); } @@ -281,58 +266,49 @@ void trx_brf_end(openair0_device_t *device) * \param device the hardware to use * \returns 0 on success */ -int trx_brf_get_stats(openair0_device_t *device) +static int trx_brf_get_stats(openair0_device_t *device) { - return(0); + return 0; } - /*! \brief Reset the BladeRF statistics -* \param device the hardware to use -* \returns 0 on success -*/ -int trx_brf_reset_stats(openair0_device_t *device) + * \param device the hardware to use + * \returns 0 on success + */ +static int trx_brf_reset_stats(openair0_device_t *device) { - return(0); + return 0; } - /*! \brief Stop BladeRF * \param card the hardware to use * \returns 0 in success */ -int trx_brf_stop(openair0_device_t *device) +static int trx_brf_stop(openair0_device_t *device) { - return(0); + return 0; } - /*! \brief Set frequencies (TX/RX) * \param device the hardware to use * \param openair0_cfg1 openair0 Config structure (ignored. It is there to comply with RF common API) * \returns 0 in success */ -int trx_brf_set_freq(openair0_device_t *device, openair0_config_t *openair0_cfg1) +static int trx_brf_set_freq(openair0_device_t *device, openair0_config_t *openair0_cfg1) { - int status; - brf_state_t *brf = (brf_state_t *)device->priv; - openair0_config_t *openair0_cfg = (openair0_config_t *)device->openair0_cfg; + int status; + brf_state_t *brf = device->priv; + openair0_config_t *openair0_cfg = (openair0_config_t *)device->openair0_cfg; + unsigned int tx_freq = (unsigned int)openair0_cfg->tx_freq[0]; + status = bladerf_set_frequency(brf->dev, BLADERF_CHANNEL_TX(0), tx_freq); + BLADERF_CHECK(status == 0, "Set TX frequency %u", tx_freq); - if ((status=bladerf_set_frequency(brf->dev, BLADERF_MODULE_TX, (unsigned int) openair0_cfg->tx_freq[0])) != 0) { - fprintf(stderr,"Failed to set TX frequency: %s\n",bladerf_strerror(status)); - brf_error(status); - } else - printf("[BRF] set TX Frequency to %u\n", (unsigned int) openair0_cfg->tx_freq[0]); - - if ((status=bladerf_set_frequency(brf->dev, BLADERF_MODULE_RX, (unsigned int) openair0_cfg->rx_freq[0])) != 0) { - fprintf(stderr,"Failed to set RX frequency: %s\n",bladerf_strerror(status)); - brf_error(status); - } else - printf("[BRF] set RX frequency to %u\n",(unsigned int)openair0_cfg->rx_freq[0]); - - return(0); + unsigned int rx_freq = (unsigned int)openair0_cfg->rx_freq[0]; + status = bladerf_set_frequency(brf->dev, BLADERF_CHANNEL_RX(0), rx_freq); + BLADERF_CHECK(status == 0, "Set RX frequency %u", rx_freq); + return 0; } @@ -341,13 +317,14 @@ int trx_brf_set_freq(openair0_device_t *device, openair0_config_t *openair0_cfg1 * \param openair0_cfg openair0 Config structure * \returns 0 in success */ -int trx_brf_set_gains(openair0_device_t *device, openair0_config_t *openair0_cfg) +static int trx_brf_set_gains(openair0_device_t *device, openair0_config_t *openair0_cfg) { - return(0); + return 0; } -int trx_brf_write_init(openair0_device_t *device) + +static int trx_brf_write_init(openair0_device_t *device) { - return 0; + return 0; } typedef struct channel_config { @@ -542,16 +519,4 @@ int device_init(openair0_device_t *device, openair0_config_t *openair0_cfg) return 0; } - - -/*! \brief bladeRF error report - * \param status - * \returns 0 on success - */ -int brf_error(int status) -{ - fprintf(stderr, "[BRF] brf_error: %s\n", bladerf_strerror(status)); - exit(-1); - return status; // or status error code -} /*@}*/ From f83b53d6d1f57b9abd06b1a2760a89992cabef16 Mon Sep 17 00:00:00 2001 From: Reem Bahsoun Date: Wed, 4 Feb 2026 09:33:31 +0100 Subject: [PATCH 11/15] Update BladeRF documentation --- doc/README.md | 2 +- radio/BLADERF/README | 138 ------------------------------------- radio/BLADERF/README.md | 148 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 149 insertions(+), 139 deletions(-) delete mode 100644 radio/BLADERF/README create mode 100644 radio/BLADERF/README.md diff --git a/doc/README.md b/doc/README.md index 022174a4e7..5f61489893 100644 --- a/doc/README.md +++ b/doc/README.md @@ -103,7 +103,7 @@ Some directories under `radio` contain READMEs: - [RFsimulator](../radio/rfsimulator/README.md) - [USRP](../radio/USRP/README.md) -- [BladeRF](../radio/BLADERF/README) +- [BladeRF](../radio/BLADERF/README.md) - [IQPlayer](../radio/iqplayer/DOC/iqrecordplayer_usage.md), and [general documentation](./iqrecordplayer_usage.md) - [fhi_72](../radio/fhi_72/README.md) - [vrtsim](../radio/vrtsim/README.md) diff --git a/radio/BLADERF/README b/radio/BLADERF/README deleted file mode 100644 index c93c938baf..0000000000 --- a/radio/BLADERF/README +++ /dev/null @@ -1,138 +0,0 @@ -BladeRF documentation -===================== - -As of 2018-11-06, the bladeRF support is not fully automatic and requires -some manual settings before use. This documentation is the ultimate source -of information. If something described in this file does not work or does -not correspond to the reality, then contact us so we can fix the problems -and update this documentation. - -1. Install bladeRF 2.0 libraries. - - As of now, it's better to install from source. - So, do not run: ./build_oai -I -w BLADERF - (That is: do not include '-w BLADERF'.) - - Instead, follow the instructions at: https://github.com/Nuand/bladeRF - - If you already had some bladeRF software installed using automatic - methods, first remove it by hand ('apt-get purge bladeRF' or something - similar, you can get the list of installed bladeRF packages by running - 'dpkg -l|grep -i blade', remove them all). - -2. Update the device. - - Download the latest FX3 firmware and FPGA images from Nuand's website. - As of writing, this is: - - https://github.com/Nuand/bladeRF/wiki - - That points to the following pages. - For FX3: - - http://www.nuand.com/fx3_images/ - - For FPGA: - - http://www.nuand.com/fpga_images/ - - Install FX3 firmware: - - sudo bladeRF-cli -f bladeRF_fw_latest.img - - Install FPGA image (this is for BladeRF x40): - - sudo bladeRF-cli -L hostedx40-latest.rbf - - Retrieve calibration information: - - sudo bladeRF-cli -i - info - - That outputs the serial number of your device. - - Go to: - - https://www.nuand.com/calibration - - And enter your serial number. - The website tells you to run something like: - - sudo bladeRF-cli -i - flash_init_cal 40 0x9271 - - Actual values depend on your device and serial number. - -3. Calibrate the bladeRF device. - - We will work with band 7 on 2.68GHz with a bandwidth of 5 MHz (25 RBs). - - Plug the bladeRF device, then run: - - sudo bladeRF-cli -i - set frequency tx 2680000000 - set frequency rx 2560000000 - set gain rx 60 - set gain tx 60 - set bandwidth 5000000 - set samplerate 7680000 - cal lms - cal lms - cal lms - cal dc rxtx - cal dc rxtx - cal dc rxtx - -4. Tune the RX gain using the enb tracer. - - Run the softmodem and the 'enb' tracer. For instructions, see: - - https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/T/basic - - In the enb window, check the 'input signal'. You should see some blue - signal as seen at: - - https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/T/enb - - (the 'Time signal power' plot). - - The level should be around 30. - - If it's not around 30 then edit your configuration file and modify - the value 'max_rxgain' in the section 'RUs'. - - The configuration file to use is: - - configuration/bladeRF/enb-band7-5mhz.conf - - In the configuration file, you also need to set the correct values for: - - - tracking_area_code - - plmn_list: mcc, mnc, mnc_length - - mme_ip_address: this is the IP address used by the computer running - the softmodem to connect to the EPC - - NETWORK_INTERFACES: all the ENB*ADDRESS* variables have to point - to the IP address of the EPC machine - -5. You're good to go. - - You can now connect a UE and pass some traffic. If everything is well - configured you can expect more than 16 Mb/s of throughput in the downlink - using iperf and more than 8 Mb/s in the uplink. Looking at the logs, you - should find lines containing 'PHR 40' and 'CQI 15'. If your values are - lower then your setup may need some adjustments. - -6. In case of problems. - - If the performance of the softmodem is very bad, you can stop it and - run the calibration again, without setting the parameters (frequencies, - gains, etc.). Just run: - - sudo bladeRF-cli -i - cal lms - cal dc rxtx - - That may help. - - Be sure to use proper radio equipment (duplexer, antennas, clean - environment without interferences). diff --git a/radio/BLADERF/README.md b/radio/BLADERF/README.md new file mode 100644 index 0000000000..d2ac6e1547 --- /dev/null +++ b/radio/BLADERF/README.md @@ -0,0 +1,148 @@ +# BladeRF 2.0 Micro Documentation + +[TOC] + +## Install BladeRF 2.0 Micro Libraries + +You can install the BladeRF library by using `build_oai -I -w BLADERF`, which +will install it from the package manager if the distribution supports it, or +falls back to a build from source otherwise. + +If you intentionally want to install BladeRF from source, you can follow +[Nuand's Getting Started +guide](https://github.com/Nuand/bladeRF/wiki/Getting-Started%3A-Linux#building-bladerf-libraries-and-tools-from-source) +to do so. + +## Configure the device + +### Image Flash + +Download the latest FX3 firmware and FPGA images from Nuand's website. There +are [fx3 images](http://www.nuand.com/fx3_images/) and [FPGA +images](http://www.nuand.com/fpga_images/). Download and save the corresponding +files to your computer, then install the FX3 firmware + + sudo bladeRF-cli -f bladeRF_fw_latest.img + +and install the FPGA image (this is x40): + + sudo bladeRF-cli -L hostedx40-latest.rbf + +### Use of the configuration file + +This configuration will help the bladeRF board to load the bitstream images +automatically, and can be used to set some options automatically that are not +configured by OAI. + +Create the bladeRF config file: + +```bash +$ cat ~/.config/Nuand/bladeRF/bladerf.conf +# Load the hostedx40.rbf FPGA image, set the trim DAC, and +# configure the frequency +fpga ~/.config/Nuand/bladeRF/image.rbf +# trimdac 592 +# frequency 2.4G +``` + +More information is available at [Nuand's +website](https://nuand.com/libbladeRF-doc/v2.5.0/configfile.html). + +### Useful commands for `bladerf-cli` + +`bladeRF-cli` can be used to query various device details. + +Show the version of bladeRF and device details + + bladeRF-cli --exec version + bladeRF-cli --exec info + +Probe for a specific device + + bladeRF-cli --probe + +Print some information on device capabilities and current configuration +(bandwidth, frequency, clocking and sample rate, various features) + + bladeRF-cli --exec print + +### Calibration + +Retrieve calibration serial number: + + bladerf-cli --exec info + +Go to the [Nuand calibration page](https://www.nuand.com/calibration) and enter +your serial number. The website tells you to run something like: + + sudo bladeRF-cli -i + flash_init_cal 40 0x9271 + +Actual values depend on your device and serial number. + +You can also rerun a calibration like so + + sudo bladeRF-cli -i + cal lms + cal dc rxtx + +## OAI + +### Build BladeRF driver + +You can use `build_oai` to build with BladeRF support, e.g., + + cd openairinterface5g/cmake_targets/ + ./build_oai --ninja --nrUE --gNB -w BLADERF + +or you can use cmake directly + + cd openairinterface5g/ + cmake -B build -G Ninja -DOAI_BLADERF=ON + cmake --build build -t oai_bladerfdevif # to build only the driver + cmake --build build # to build it all + +For more information about the build, please refer to [the build +documentation](../../doc/BUILD.md). + +### Adapt the OAI-gNB configuration file to your system + +You can start from a [sample BladeRF configuration +fiel](../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.51PRB.bladerf20xa0.conf). + +The only BladeRF-specific configuration resides in `RUs.[0].sdr_addrs`. This +string is passed to +[`bladerf_open()`](https://www.nuand.com/libbladeRF-doc/v2.6.0/group___f_n___i_n_i_t.html#gab341ac98615f393da9158ea59cdb6a24) +and can be used to select a specific BladeRF device. For instance, to open a +specific device with serial 730f5a36545849d9aa71ca6cf50e8ca0 on USB, you would +add `libusb: serial=730f5a36545849d9aa71ca6cf50e8ca0`. + +The TX gain is automatically chosen to be the maximum, and can be reduced with +`att_tx`. The RX gain is taken from `RUs.[0].max_rxgain`, and can be attenuated +with `att_rx`. + +The rest of the paramaters (PLMN, frequencies, IP addresses) is the same as in +any other configuration. Refer to the [general +tutorials](../..//doc/NR_SA_Tutorial_OAI_CN5G.md) for more information. + +### Run the setup + +Assuming you built from source above: + + cd ~/openairinterface5g/build/ + sudo ./nr-softmodem -O ../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.51PRB.bladerf20xa0.conf -E + +### In case of problems + +Refer back to the calibration section above. If not done yet, consider +calibrating your device. + +You can get more logs from BladeRF. To do so, you have to edit the code and +modify this line inside [`bladerf_lib.c`](./bladerf_lib.c). + +```patch +- bladerf_log_set_verbosity(BLADERF_LOG_LEVEL_INFO); ++ bladerf_log_set_verbosity(BLADERF_LOG_LEVEL_VERBOSE); +``` + +in function `device_init()`. From 0a585c123589bcc6bb7b824c75593a60bbdc7fc0 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 4 Feb 2026 09:35:19 +0100 Subject: [PATCH 12/15] Add BladeRF configs --- .../gnb.sa.band78.106prb.bladerf2.0xa4.conf | 229 ++++++++++++++++++ .../gnb.sa.band78.51PRB.bladerf2.0xa4.conf | 229 ++++++++++++++++++ 2 files changed, 458 insertions(+) create mode 100644 targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.106prb.bladerf2.0xa4.conf create mode 100644 targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.51PRB.bladerf2.0xa4.conf diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.106prb.bladerf2.0xa4.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.106prb.bladerf2.0xa4.conf new file mode 100644 index 0000000000..d53e3137fe --- /dev/null +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.106prb.bladerf2.0xa4.conf @@ -0,0 +1,229 @@ +Active_gNBs = ( "gNB-OAI"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +gNBs = +( + { + ////////// Identification parameters: + gNB_ID = 0xe00; + gNB_name = "gNB-OAI"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + plmn_list = ({ mcc = 001; mnc = 01; mnc_length = 2; snssaiList = ({ sst = 1; }) }); + + nr_cellid = 12345678L; + + ////////// Physical parameters: + + min_rxtxtime = 2; + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + +# downlinkConfigCommon + #frequencyInfoDL + # this is 3300.60 MHz + 53*12*30e-3 MHz = 3319.68 + absoluteFrequencySSB = 621312; + dl_frequencyBand = 78; + # this is 3300.60 MHz + dl_absoluteFrequencyPointA = 620040; + #scs-SpecificCarrierList + dl_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing = 1; + dl_carrierBandwidth = 106; + #initialDownlinkBWP + #genericParameters + # this is RBstart=0,L=106 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth = 28875; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 1; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 11; + initialDLBWPsearchSpaceZero = 0; + + + + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand = 78; + #scs-SpecificCarrierList + ul_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 1; + ul_carrierBandwidth = 106; + pMax = 20; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 28875; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialULBWPsubcarrierSpacing = 1; + #rach-ConfigCommon + #rach-ConfigGeneric + prach_ConfigurationIndex = 98; +#prach_msg1_FDM +#0 = one, 1=two, 2=four, 3=eight + prach_msg1_FDM = 0; + prach_msg1_FrequencyStart = 0; + zeroCorrelationZoneConfig = 12; + preambleReceivedTargetPower = -96; +#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) + preambleTransMax = 6; +#powerRampingStep +# 0=dB0,1=dB2,2=dB4,3=dB6 + powerRampingStep = 1; +#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR +#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4; +#one (0..15) 4,8,12,16,...60,64 + ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15; +#ra_ContentionResolutionTimer +#(0..7) 8,16,24,32,40,48,56,64 + ra_ContentionResolutionTimer = 7; + rsrp_ThresholdSSB = 19; +#prach-RootSequenceIndex_PR +#1 = 839, 2 = 139 + prach_RootSequenceIndex_PR = 2; + prach_RootSequenceIndex = 1; + # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex + # + msg1_SubcarrierSpacing = 1, +# restrictedSetConfig +# 0=unrestricted, 1=restricted type A, 2=restricted type B + restrictedSetConfig = 0, + + msg3_DeltaPreamble = 1; + p0_NominalWithGrant =-90; + +# pucch-ConfigCommon setup : +# pucchGroupHopping +# 0 = neither, 1= group hopping, 2=sequence hopping + pucchGroupHopping = 0; + hoppingId = 40; + p0_nominal = -90; + + ssb_PositionsInBurst_Bitmap = 1; + +# ssb_periodicityServingCell +# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 + ssb_periodicityServingCell = 2; + +# dmrs_TypeA_position +# 0 = pos2, 1 = pos3 + dmrs_TypeA_Position = 0; + +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + subcarrierSpacing = 1; + + + #tdd-UL-DL-ConfigurationCommon +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + referenceSubcarrierSpacing = 1; + # pattern1 + # dl_UL_TransmissionPeriodicity + # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 + dl_UL_TransmissionPeriodicity = 6; + nrofDownlinkSlots = 7; + nrofDownlinkSymbols = 6; + nrofUplinkSlots = 2; + nrofUplinkSymbols = 4; + + ssPBCH_BlockPower = -25; + } + + ); + + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + ////////// AMF parameters: + amf_ip_address = ({ ipv4 = "192.168.70.132"; }); + + + NETWORK_INTERFACES : + { + GNB_IPV4_ADDRESS_FOR_NG_AMF = "192.168.70.129/24"; + GNB_IPV4_ADDRESS_FOR_NGU = "192.168.70.129/24"; + GNB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + + } +); + +MACRLCs = ( +{ + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + pusch_TargetSNRx10 = 200; + pucch_TargetSNRx10 = 200; +} +); + +L1s = ( +{ + num_cc = 1; + tr_n_preference = "local_mac"; + prach_dtx_threshold = 200; +} +); + +RUs = ( +{ + local_rf = "yes" + nb_tx = 1 + nb_rx = 1 + att_tx = 0; + att_rx = 0; + bands = [78]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 75; + eNB_instances = [0]; + sdr_addrs = "libusb: serial=730f5a36545849d9aa71ca6cf50e8ca0" +} +); + +security = { + # preferred ciphering algorithms + # the first one of the list that an UE supports in chosen + # valid values: nea0, nea1, nea2, nea3 + ciphering_algorithms = ( "nea0" ); + + # preferred integrity algorithms + # the first one of the list that an UE supports in chosen + # valid values: nia0, nia1, nia2, nia3 + integrity_algorithms = ( "nia2", "nia0" ); + + # setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter + # what 'ciphering_algorithms' configures; same thing for 'drb_integrity' + drb_ciphering = "yes"; + drb_integrity = "no"; +}; + +log_config : +{ + global_log_level = "info"; + hw_log_level = "info"; + phy_log_level = "info"; + mac_log_level = "info"; + rlc_log_level = "info"; + pdcp_log_level = "info"; + rrc_log_level = "info"; +}; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.51PRB.bladerf2.0xa4.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.51PRB.bladerf2.0xa4.conf new file mode 100644 index 0000000000..b48977847b --- /dev/null +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.51PRB.bladerf2.0xa4.conf @@ -0,0 +1,229 @@ +Active_gNBs = ( "gNB-OAI"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +gNBs = +( + { + ////////// Identification parameters: + gNB_ID = 0xe00; + gNB_name = "gNB-OAI"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + plmn_list = ({ mcc = 001; mnc = 01; mnc_length = 2; snssaiList = ({ sst = 1; }) }); + + nr_cellid = 12345678L; + + ////////// Physical parameters: + + min_rxtxtime = 2; + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + +# downlinkConfigCommon + #frequencyInfoDL + # this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP) + absoluteFrequencySSB = 636672; + dl_frequencyBand = 78; + # this is 3600 MHz + dl_absoluteFrequencyPointA = 636060; + #scs-SpecificCarrierList + dl_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing = 1; + dl_carrierBandwidth = 51; + #initialDownlinkBWP + #genericParameters + # this is RBstart=27,L=48 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth = 13750; # 6366 12925 12956 28875 12952 +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 1; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 11; + initialDLBWPsearchSpaceZero = 0; + + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand = 78; + #scs-SpecificCarrierList + ul_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 1; + ul_carrierBandwidth = 51; + pMax = 20; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 13750; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialULBWPsubcarrierSpacing = 1; + #rach-ConfigCommon + #rach-ConfigGeneric + prach_ConfigurationIndex = 98; +#prach_msg1_FDM +#0 = one, 1=two, 2=four, 3=eight + prach_msg1_FDM = 0; + prach_msg1_FrequencyStart = 0; + zeroCorrelationZoneConfig = 13; + preambleReceivedTargetPower = -96; +#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) + preambleTransMax = 6; +#powerRampingStep +# 0=dB0,1=dB2,2=dB4,3=dB6 + powerRampingStep = 1; +#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR +#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4; +#oneHalf (0..15) 4,8,12,16,...60,64 + ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 14; +#ra_ContentionResolutionTimer +#(0..7) 8,16,24,32,40,48,56,64 + ra_ContentionResolutionTimer = 7; + rsrp_ThresholdSSB = 19; +#prach-RootSequenceIndex_PR +#1 = 839, 2 = 139 + prach_RootSequenceIndex_PR = 2; + prach_RootSequenceIndex = 1; + # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex + # + msg1_SubcarrierSpacing = 1, +# restrictedSetConfig +# 0=unrestricted, 1=restricted type A, 2=restricted type B + restrictedSetConfig = 0, + + msg3_DeltaPreamble = 1; + p0_NominalWithGrant =-90; + +# pucch-ConfigCommon setup : +# pucchGroupHopping +# 0 = neither, 1= group hopping, 2=sequence hopping + pucchGroupHopping = 0; + hoppingId = 40; + p0_nominal = -90; + ssb_PositionsInBurst_Bitmap = 1; + +# ssb_periodicityServingCell +# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 + ssb_periodicityServingCell = 2; + +# dmrs_TypeA_position +# 0 = pos2, 1 = pos3 + dmrs_TypeA_Position = 0; + +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + subcarrierSpacing = 1; + + + #tdd-UL-DL-ConfigurationCommon +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + referenceSubcarrierSpacing = 1; + # pattern1 + # dl_UL_TransmissionPeriodicity + # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 + dl_UL_TransmissionPeriodicity = 6; + nrofDownlinkSlots = 7; + nrofDownlinkSymbols = 6; + nrofUplinkSlots = 2; + nrofUplinkSymbols = 4; + + ssPBCH_BlockPower = -25; + } + + ); + + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// AMF parameters: + amf_ip_address = ({ ipv4 = "192.168.70.132"; }); + + + NETWORK_INTERFACES : + { + GNB_IPV4_ADDRESS_FOR_NG_AMF = "192.168.70.129/24"; + GNB_IPV4_ADDRESS_FOR_NGU = "192.168.70.129/24"; + GNB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + + } +); + +MACRLCs = ( +{ + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + pusch_TargetSNRx10 = 200; + pucch_TargetSNRx10 = 200; +} +); + +L1s = ( +{ + num_cc = 1; + tr_n_preference = "local_mac"; + prach_dtx_threshold = 150; + pucch0_dtx_threshold = 100; + ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0 +} +); + +RUs = ( +{ + local_rf = "yes" + nb_tx = 1 + nb_rx = 1 + att_tx = 0; + att_rx = 0; + bands = [78]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 75; + eNB_instances = [0]; + sdr_addrs = "libusb: serial=730f5a36545849d9aa71ca6cf50e8ca0" +} +); + +security = { + # preferred ciphering algorithms + # the first one of the list that an UE supports in chosen + # valid values: nea0, nea1, nea2, nea3 + ciphering_algorithms = ( "nea0" ); + + # preferred integrity algorithms + # the first one of the list that an UE supports in chosen + # valid values: nia0, nia1, nia2, nia3 + integrity_algorithms = ( "nia2", "nia0" ); + + # setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter + # what 'ciphering_algorithms' configures; same thing for 'drb_integrity' + drb_ciphering = "yes"; + drb_integrity = "no"; +}; + +log_config : +{ + global_log_level = "info"; + hw_log_level = "info"; + phy_log_level = "info"; + mac_log_level = "info"; + rlc_log_level = "info"; + pdcp_log_level = "info"; + rrc_log_level = "info"; +}; From 16c333b1a3850a79647ca2bf6387b1b14391b821 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 4 Feb 2026 17:01:51 +0100 Subject: [PATCH 13/15] Compile everything in Ubuntu builder Compile all targets in Ubuntu build to avoid breakage of software. Remove ldd in build dockerfile, as we don't need that (can also be inspected manually). --- docker/Dockerfile.build.ubuntu | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/docker/Dockerfile.build.ubuntu b/docker/Dockerfile.build.ubuntu index 9ccd921043..50c31f1357 100644 --- a/docker/Dockerfile.build.ubuntu +++ b/docker/Dockerfile.build.ubuntu @@ -42,22 +42,15 @@ RUN \ # Mount CPM package cache --mount=type=cache,target=/root/.cache/cpm/ \ /bin/sh oaienv && \ - cd cmake_targets && \ - mkdir -p log && \ - ./build_oai -c --ninja \ - --eNB --gNB --RU --UE --nrUE \ - --build-lib "telnetsrv enbscope uescope nrscope" \ - -w USRP -t Ethernet \ - --build-e2 --cmake-opt -DKPM_VERSION=$KPM_VERSION --cmake-opt -DE2AP_VERSION=$E2AP_VERSION \ - --cmake-opt -DOAI_VRTSIM_TAPS_CLIENT=ON \ - --noavx512 \ - --build-tool-opt -k10 \ - --cmake-opt -DCMAKE_C_FLAGS="-Werror" --cmake-opt -DCMAKE_CXX_FLAGS="-Werror" $BUILD_OPTION && \ - # Mainly to see if the sanitize option was perfectly executed - echo "---- ldd on executables ----" && \ - ldd ran_build/build/*softmodem* ran_build/build/nr-cuup ran_build/build/oairu && \ - echo "---- ldd on shared libraries ----" && \ - ldd ran_build/build/*.so + mkdir -p cmake_targets/ran_build/build && \ + cd cmake_targets/ran_build/build && \ + cmake ../../../ -GNinja \ + -DENABLE_TELNETSRV=ON -DENABLE_ENBSCOPE=ON -DENABLE_UESCOPE=ON -DENABLE_NRSCOPE=ON \ + -DOAI_USRP=ON -DOAI_ETHERNET=ON -DOAI_VRTSIM_TAPS_CLIENT=ON \ + -DE2_AGENT=ON -DKPM_VERSION=KPM_V3_00 -DE2AP_VERSION=E2AP_V3 \ + -DAVX512=OFF && \ + # -DCMAKE_C_FLAGS=-Werror -DCMAKE_CXX_FLAGS=-Werror && \ + ninja ## Build FlexRIC for SM Models RUN \ From 054d0f55cd62f201f7d0e083926cf53305b31d2e Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 5 Feb 2026 00:24:06 +0100 Subject: [PATCH 14/15] base&build: install with BladeRF --- docker/Dockerfile.base.ubuntu | 2 +- docker/Dockerfile.build.ubuntu | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker/Dockerfile.base.ubuntu b/docker/Dockerfile.base.ubuntu index 3d7e162544..b0eb5c4d32 100644 --- a/docker/Dockerfile.base.ubuntu +++ b/docker/Dockerfile.base.ubuntu @@ -86,4 +86,4 @@ COPY oaienv . RUN /bin/sh oaienv && \ cd cmake_targets && \ mkdir -p log && \ - ./build_oai -I -w USRP --install-optional-packages + ./build_oai -I -w USRP -w BLADERF --install-optional-packages diff --git a/docker/Dockerfile.build.ubuntu b/docker/Dockerfile.build.ubuntu index 50c31f1357..bc2ed577a6 100644 --- a/docker/Dockerfile.build.ubuntu +++ b/docker/Dockerfile.build.ubuntu @@ -46,7 +46,7 @@ RUN \ cd cmake_targets/ran_build/build && \ cmake ../../../ -GNinja \ -DENABLE_TELNETSRV=ON -DENABLE_ENBSCOPE=ON -DENABLE_UESCOPE=ON -DENABLE_NRSCOPE=ON \ - -DOAI_USRP=ON -DOAI_ETHERNET=ON -DOAI_VRTSIM_TAPS_CLIENT=ON \ + -DOAI_USRP=ON -DOAI_BLADERF=ON -DOAI_ETHERNET=ON -DOAI_VRTSIM_TAPS_CLIENT=ON \ -DE2_AGENT=ON -DKPM_VERSION=KPM_V3_00 -DE2AP_VERSION=E2AP_V3 \ -DAVX512=OFF && \ # -DCMAKE_C_FLAGS=-Werror -DCMAKE_CXX_FLAGS=-Werror && \ From abe3ee96247306f3320b77eeb5f3aaf479778efe Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 5 Feb 2026 02:05:38 +0100 Subject: [PATCH 15/15] Fixes bladerf install scripts - at least in CI, there is no bladerf, so don't try to upgrade a firmware (we don't do that either with USRPs) - the base distro for ubuntu is debian --- cmake_targets/tools/build_helper | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index 4e832891eb..50615e42ea 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -346,19 +346,10 @@ install_bladerf_driver_from_source(){ make $SUDO make install $SUDO ldconfig - echo "Downloading FPGA and firmware images" - cd /tmp/bladeRF - #wget has been removed from default dependencies, so we must be sure that's installed - $SUDO $INSTALLER -y install wget - wget --tries=3 --retry-connrefused https://www.nuand.com/fx3/bladeRF_fw_latest.img - wget --tries=3 --retry-connrefused https://www.nuand.com/fpga/hostedx40-latest.rbf - sudo mkdir -p /usr/share/Nuand/bladeRF - sudo mv bladeRF_fw_latest.img /usr/share/Nuand/bladeRF/bladeRF_fw.img - sudo mv hostedx40-latest.rbf /usr/share/Nuand/bladeRF/hostedx40.rbf } check_install_bladerf_driver(){ - if [[ "$OS_DISTRO" == "ubuntu" ]]; then + if [[ "$OS_BASEDISTRO" == "debian" ]]; then $SUDO apt-get install -y bladerf libbladerf-dev $SUDO apt-get install -y bladerf-firmware-fx3 $SUDO apt-get install -y bladerf-fpga-hostedx40