diff --git a/CMakeLists.txt b/CMakeLists.txt index 410aa6497e..015e66e46d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2092,7 +2092,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 -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 -Wl,--end-group m pthread ITTI dl nr_ue_phy_meas physim_common softmodem_common ) diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index c6d1276e88..c9e268407d 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -36,9 +36,8 @@ 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 -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" @@ -254,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") @@ -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" @@ -424,27 +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 ] && [ ! "$DISABLE_HARDWARE_DEPENDENCY" == "True" ]; 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 - 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 + done fi if [ "$INSTALL_OPTIONAL" = "1" ] ; then diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index 1b025e65a1..74d45cda9b 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 @@ -369,10 +360,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" ] ) diff --git a/common/utils/nr/nr_common.c b/common/utils/nr/nr_common.c index 75715ef369..b370b8da66 100644 --- a/common/utils/nr/nr_common.c +++ b/common/utils/nr/nr_common.c @@ -1381,6 +1381,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] #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; /** @addtogroup _BLADERF_PHY_RF_INTERFACE_ * @{ */ -//! Number of BladeRF devices -int num_devices=0; +#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; \ + } -/*These items configure the underlying asynch stream used by the the sync interface. - */ +const bladerf_format format = BLADERF_FORMAT_SC16_Q11_META; -/*! \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) +static const char *ch_dir(bladerf_channel ch) { - return 0; + 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 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 */ -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, - BLADERF_FORMAT_SC16_Q11_META, - 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, - BLADERF_FORMAT_SC16_Q11_META, - 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_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", + 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_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", + 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_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_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; } /*! \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 @@ -128,46 +165,37 @@ 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 @@ -181,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); } @@ -245,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; } @@ -305,633 +317,50 @@ 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); -} -int trx_brf_write_init(openair0_device_t *device) -{ - return 0; + 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) +static int trx_brf_write_init(openair0_device_t *device) { - 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++; - } - + return 0; } +typedef struct channel_config { + bladerf_channel channel; + unsigned int frequency; + unsigned int sample_rate; + unsigned int bandwidth; + int gain; +} channel_config_t; -/*! \brief Calibrate LMSSDR RF - * \param device the hardware to use - */ -void calibrate_rf(openair0_device_t *device) + +static int configure_channel(struct bladerf *dev, channel_config_t *c) { - /* TODO: this function does not seem to work. Disabled until fixed. */ - return; + int status; + unsigned int actual_value = 0; + const char *dir = ch_dir(c->channel); - 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; + status = bladerf_set_frequency(dev, c->channel, c->frequency); + BLADERF_CHECK(status == 0, "Set %s frequency %u", dir, c->frequency); - // 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); + 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); - // fill TX buffer with fs/8 complex sinusoid - j=0; - for (i=0; ichannel, c->bandwidth, &actual_value); + BLADERF_CHECK(status == 0, "Set %s bandwidth %u (is %u)", dir, c->bandwidth, actual_value); - offIold=offQold=2048; - 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); - for (i=0; i<10; i++) - trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); + status = bladerf_set_gain(dev, c->channel, c->gain); + BLADERF_CHECK(status == 0, "Set %s gain %u", dir, c->gain); - for (meanIold=meanQold=i=j=0; i (%d,%d)\n",offIold,offQold,meanIold,meanQold); + bladerf_gain g; + status = bladerf_get_gain(dev, c->channel, &g); + BLADERF_CHECK(status == 0, "Get %s gain: %u", dir, g); - 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); + 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 @@ -939,266 +368,155 @@ void calibrate_rf(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; - } - openair0_cfg->rx_gain_calib_table = calib_table_fx4; + LOG_E(HW, "Error: unknown sampling rate %f\n", openair0_cfg->sample_rate); + return -1; + break; + } - // 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; + brf.tx_timeout_ms = 2000; + brf.buffer_size = (unsigned int)openair0_cfg->samples_per_packet; + brf.sample_rate = (unsigned int)openair0_cfg->sample_rate; - memset(&brf->meta_rx, 0, sizeof(brf->meta_rx)); - memset(&brf->meta_tx, 0, sizeof(brf->meta_tx)); + 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); - 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); + memset(&brf.meta_rx, 0, sizeof(brf.meta_rx)); + memset(&brf.meta_tx, 0, sizeof(brf.meta_tx)); - 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 + // 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 ((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 (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; } - 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]); + /** [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"); + status = bladerf_set_gain_mode(brf.dev, BLADERF_CHANNEL_RX(0), BLADERF_GAIN_MGC); + BLADERF_CHECK(status == 0, "Disable AGC"); + 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); - 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); + // 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_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); - - 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); - } 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]); - - - /* 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"); - - // 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 - * - 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->Mod_id = num_devices++; - 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; - - 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) { - 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; -} - - -/*! \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 -} - - -/*! \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; - } + return 0; } /*@}*/ 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 */ 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"; +};