diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 5182f597e341a12415ff840b37c0f10435123acc..c536d90ab66cb36e053770b115d57a83d2a6d4fa 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -484,7 +484,7 @@ include_directories ("${X2AP_DIR}") add_list1_option(NB_ANTENNAS_RX "2" "Number of antennas in reception" "1" "2" "4") add_list1_option(NB_ANTENNAS_TX "4" "Number of antennas in transmission" "1" "2" "4") -add_list2_option(RF_BOARD "EXMIMO" "RF head type" "None" "EXMIMO" "OAI_USRP" "OAI_BLADERF" "CPRIGW" "OAI_LMSSDR") +add_list2_option(RF_BOARD "EXMIMO" "RF head type" "None" "EXMIMO" "OAI_USRP" "OAI_BLADERF" "CPRIGW" "OAI_LMSSDR" "OAI_ADRV9371_ZC706") add_list2_option(TRANSP_PRO "None" "Transport protocol type" "None" "ETHERNET") #NOKIA config enhancement @@ -507,6 +507,11 @@ set (SHLIB_LOADER_SOURCES ) # include RF devices / transport protocols library modules ###################################################################### +if (HWLAT) + add_definitions(-DHWLAT ) +endif() + + include_directories("${OPENAIR_TARGETS}/ARCH/EXMIMO/USERSPACE/LIB/") include_directories ("${OPENAIR_TARGETS}/ARCH/EXMIMO/DEFS/") @@ -761,6 +766,9 @@ include_directories("${OPENAIR3_DIR}/UDP") include_directories("${OPENAIR3_DIR}/GTPV1-U") include_directories("${OPENAIR_DIR}/targets/COMMON") include_directories("${OPENAIR_DIR}/targets/ARCH/COMMON") +include_directories("${OPENAIR_DIR}/targets/ARCH/ADRV9371_ZC706/USERSPACE/LIB/") +include_directories("${OPENAIR_DIR}/targets/ARCH/ADRV9371_ZC706/USERSPACE/libini/") +include_directories("${OPENAIR_DIR}/targets/ARCH/ADRV9371_ZC706/DEFS/") include_directories("${OPENAIR_DIR}/targets/ARCH/EXMIMO/USERSPACE/LIB/") include_directories("${OPENAIR_DIR}/targets/ARCH/EXMIMO/DEFS") include_directories("${OPENAIR2_DIR}/ENB_APP") @@ -2063,6 +2071,38 @@ target_link_libraries (lte-softmodem-nos1 pthread m ${CONFIG_LIBRARIES} rt crypt target_link_libraries (lte-softmodem-nos1 ${LIB_LMS_LIBRARIES}) target_link_libraries (lte-softmodem-nos1 ${T_LIB}) + +# lte-hwlat +################################################### +add_executable(lte-hwlat + ${HW_SOURCE} + ${OPENAIR_TARGETS}/RT/USER/lte-hwlat.c + ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c + ) +target_link_libraries (lte-hwlat + -Wl,--start-group + -Wl,--end-group ) + +target_link_libraries (lte-hwlat rt pthread m ) +target_link_libraries (lte-hwlat ${CMAKE_DL_LIBS} ) +target_link_libraries (lte-hwlat ${OPENAIR_TARGETS}/ARCH/ADRV9371_ZC706/slib/libadrv9371_zc706.so ) + + +# lte-hwlat-test +################################################### +add_executable(lte-hwlat-test + ${HW_SOURCE} + ${OPENAIR1_DIR}/PHY/TOOLS/time_meas.c + ${OPENAIR_TARGETS}/RT/USER/lte-hwlat2.c + ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c + ) +target_link_libraries (lte-hwlat-test + -Wl,--start-group + -Wl,--end-group ) + +target_link_libraries (lte-hwlat-test rt pthread m ) +target_link_libraries (lte-hwlat-test ${CMAKE_DL_LIBS} ) + # lte-uesoftmodem is UE implementation ####################################### @@ -2379,10 +2419,10 @@ if (${T_TRACER}) #all "add_executable" definitions (except tests, rb_tool, updatefw) lte-softmodem lte-softmodem-nos1 oaisim oaisim_nos1 dlsim_tm4 dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim - pdcchsim pucchsim prachsim syncsim + pdcchsim pucchsim prachsim syncsim lte-hwlat #all "add_library" definitions ITTI RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB - oai_exmimodevif oai_usrpdevif oai_bladerfdevif oai_lmssdrdevif + oai_adrv9371_zc706devif oai_exmimodevif oai_usrpdevif oai_bladerfdevif oai_lmssdrdevif oai_eth_transpro FLPT_MSG ASYNC_IF FLEXRAN_AGENT HASHTABLE MSC UTIL OMG_SUMO SECU_OSA SECU_CN SCHED_LIB PHY L2 default_sched remote_sched RAL CN_UTILS diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index 596b5aff7200f9133d257e19ad959a26f7c2b838..d9cad35b9e20e7fe63a68b086be1e0d34df6a6d0 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -51,6 +51,7 @@ REL="Rel14" HW="None" TP="None" NOS1=0 +HW_LATENCY=0 EPC=0 VERBOSE_COMPILE=0 CFLAGS_PROCESSOR_USER="" @@ -104,12 +105,14 @@ Options Specify conf_nvram_path (default \"$conf_nvram_path\") --UE-gen-nvram [output path] Specify gen_nvram_path (default \"$gen_nvram_path\") +--HWLAT + Makes test program for haw latency tests -r | --3gpp-release default is Rel14, Rel8 limits the implementation to 3GPP Release 8 version Rel10 limits the implementation to 3GPP Release 10 version -w | --hardware - EXMIMO, USRP, BLADERF, ETHERNET, LMSSDR, None (Default) + EXMIMO, USRP, BLADERF, ETHERNET, LMSSDR, ADRV9371_ZC706, None (Default) Adds this RF board support (in external packages installation and in compilation) -t | --transport protocol ETHERNET , None @@ -234,13 +237,16 @@ function main() { shift 2;; -w | --hardware) HW="$2" #"${i#*=}" - # Use OAI_USRP as the key word USRP is used inside UHD driver - if [ "$HW" != "BLADERF" -a "$HW" != "USRP" -a "$HW" != "LMSSDR" -a "$HW" != "None" -a "$HW" != "EXMIMO" ] ; then + # Use OAI_USRP as the key word USRP is used inside UHD driver + if [ "$HW" != "BLADERF" -a "$HW" != "USRP" -a "$HW" != "LMSSDR" -a "$HW" != "None" -a "$HW" != "EXMIMO" -a "$HW" != "ADRV9371_ZC706" ] ; then echo_fatal "Unknown HW type $HW will exit..." else if [ "$HW" == "USRP" ] ; then HW="OAI_USRP" fi + if [ "$HW" == "ADRV9371_ZC706" ] ; then + HW="OAI_ADRV9371_ZC706" + fi if [ "$HW" == "BLADERF" ] ; then HW="OAI_BLADERF" fi @@ -297,6 +303,14 @@ function main() { NOS1=1 echo_info "Will compile without S1 interface" shift;; + --HWLAT) + HWLAT=1 + echo_info "Will compile hw latency test program" + shift;; + --HWLAT_TEST) + HWLAT_TEST=1 + echo_info "Will compile hw latency test program" + shift;; --verbose-compile) VERBOSE_COMPILE=1 echo_info "Will compile with verbose instructions" @@ -397,6 +411,12 @@ function main() { fi fi + if [ "$HWLAT" = "1" ] ; then + if [ "$HW" = "None" ] ; then + echo_info "No radio head has been selected (HW set to $HW)" + fi + fi + echo_info "RF HW set to $HW" #Now we set flags to enable deadline scheduler settings #By default: USRP: disable, @@ -409,6 +429,8 @@ function main() { DEADLINE_SCHEDULER_FLAG_USER="False" elif [ "$HW" = "OAI_USRP" ] ; then DEADLINE_SCHEDULER_FLAG_USER="False" + elif [ "$HW" = "OAI_ADRV9371_ZC706" ] ; then + DEADLINE_SCHEDULER_FLAG_USER="False" elif [ "$HW" = "OAI_BLADERF" ] ; then DEADLINE_SCHEDULER_FLAG_USER="False" elif [ "$HW" = "OAI_LMSSDR" ] ; then @@ -474,6 +496,10 @@ function main() { install_usrp_uhd_driver $UHD_IMAGES_DIR fi fi + if [ "$HW" == "OAI_ADRV9371_ZC706" ] ; then + echo_info "\nInstalling packages for ADRV9371_ZC706 support" + check_install_libiio_driver + fi if [ "$HW" == "OAI_BLADERF" ] ; then echo_info "installing packages for BLADERF support" check_install_bladerf_driver @@ -811,9 +837,65 @@ function main() { libtelnetsrv.so $dbin/libtelnetsrv.so fi + # HWLAT compilation + ##################### + if [ "$HWLAT" = "1" ] ; then + + hwlat_exec=lte-hwlat + hwlat_build_dir=lte-hwlat + + echo_info "Compiling $hwlat_exec ..." + + [ "$CLEAN" = "1" ] && rm -rf $DIR/lte-hwlat/build + mkdir -p $DIR/$hwlat_build_dir/build + cmake_file=$DIR/$hwlat_build_dir/CMakeLists.txt + echo "cmake_minimum_required(VERSION 2.8)" > $cmake_file + echo "set ( CMAKE_BUILD_TYPE $CMAKE_BUILD_TYPE )" >> $cmake_file + echo "set ( RF_BOARD \"${HW}\")" >> $cmake_file + echo 'set ( PACKAGE_NAME "\"lte-hwlat\"")' >> $cmake_file + echo "set ( DEADLINE_SCHEDULER \"${DEADLINE_SCHEDULER_FLAG_USER}\" )" >>$cmake_file + echo "set ( CPU_AFFINITY \"${CPU_AFFINITY_FLAG_USER}\" )" >>$cmake_file + echo "set ( HWLAT \"${HWLAT}\" )" >>$cmake_file + echo 'include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)' >> $cmake_file + cd $DIR/$hwlat_build_dir/build + cmake .. + compilations \ + lte-hwlat lte-hwlat \ + lte-hwlat $dbin/lte-hwlat + + fi + + # HWLAT_TEST compilation + ##################### + if [ "$HWLAT_TEST" = "1" ] ; then + + hwlat_test_exec=lte-hwlat-test + hwlat_test_build_dir=lte-hwlat-test + + echo_info "Compiling $hwlat_test_exec ..." + + [ "$CLEAN" = "1" ] && rm -rf $DIR/lte-hwlat-test/build + mkdir -p $DIR/$hwlat_test_build_dir/build + cmake_file=$DIR/$hwlat_test_build_dir/CMakeLists.txt + echo "cmake_minimum_required(VERSION 2.8)" > $cmake_file + echo "set ( CMAKE_BUILD_TYPE $CMAKE_BUILD_TYPE )" >> $cmake_file + echo "set ( RF_BOARD \"${HW}\")" >> $cmake_file + echo 'set ( PACKAGE_NAME "\"lte-hwlat-test\"")' >> $cmake_file + echo "set ( DEADLINE_SCHEDULER \"${DEADLINE_SCHEDULER_FLAG_USER}\" )" >>$cmake_file + echo "set ( CPU_AFFINITY \"${CPU_AFFINITY_FLAG_USER}\" )" >>$cmake_file + echo "set ( HWLAT \"${HWLAT}\" )" >>$cmake_file + echo 'include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)' >> $cmake_file + cd $DIR/$hwlat_test_build_dir/build + cmake .. + compilations \ + lte-hwlat-test lte-hwlat-test \ + lte-hwlat-test $dbin/lte-hwlat-test + + fi + # build RF device and transport protocol libraries ##################################### - if [ "$eNB" = "1" -o "$UE" = "1" -o "$gNB" = "1" -o "$nrUE" = "1" ] ; then + if [ "$eNB" = "1" -o "$UE" = "1" -o "$gNB" = "1" -o "$nrUE" = "1" - o "$HWLAT" = "1" ] ; then build_dir=$build_dir @@ -831,6 +913,11 @@ function main() { ln -sf liboai_exmimodevif.so liboai_device.so ln -sf $dbin/liboai_exmimodevif.so.$REL $dbin/liboai_device.so echo_info "liboai_device.so is linked to EXMIMO device library" + elif [ "$HW" == "OAI_ADRV9371_ZC706" ] ; then + + ln -sf $OPENAIR_DIR/targets/ARCH/ADRV9371_ZC706/slib/libadrv9371_zc706.so liboai_device.so + + echo_info "liboai_device.so is linked to ADRV9371_ZC706 device library" elif [ "$HW" == "OAI_USRP" ] ; then compilations \ $build_dir oai_usrpdevif \ diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index 2b8123c86b796b9927ec389df6431da67e85b2c8..4d95292f088591f06cb16e9bc9a5e9e96188832f 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -242,6 +242,36 @@ install_protobuf_c_from_source(){ ) >& $protobuf_c_install_log } +install_libiio_driver_from_source(){ + libiio_install_log=$OPENAIR_DIR/cmake_targets/log/libiio_install_log.txt + echo_info "\nInstalling LibIIO driver from sources. The log file for LibIIO driver installation is here: $libiio_install_log " + ( + cd /tmp + echo "Downloading LibIIO driver" + rm -rf /tmp/libiio + git clone https://github.com/analogdevicesinc/libiio.git + cd libiio + git checkout 2016_R2 + cmake ./ + make all + $SUDO make install + ) >& $libiio_install_log +} + +check_install_libiio_driver(){ + if [[ "$OS_DISTRO" == "ubuntu" ]]; then + $SUDO apt-get install -y --allow-unauthenticated libxml2 + $SUDO apt-get install -y --allow-unauthenticated libxml2-dev + $SUDO apt-get install -y --allow-unauthenticated bison + $SUDO apt-get install -y --allow-unauthenticated flex + $SUDO apt-get install -y --allow-unauthenticated libcdk5-dev + $SUDO apt-get install -y --allow-unauthenticated cmake + $SUDO apt-get install -y --allow-unauthenticated libaio-dev + $SUDO apt-get install -y --allow-unauthenticated libavahi-client-dev + install_libiio_driver_from_source + fi +} + install_usrp_uhd_driver_from_source(){ uhd_install_log=$OPENAIR_DIR/cmake_targets/log/uhd_install_log.txt echo_info "\nInstalling UHD driver from sources. The log file for UHD driver installation is here: $uhd_install_log " diff --git a/oaienv b/oaienv index f6b298debf69e2e24c2c65cce458291b9ff0a513..d9a540697b445bba06e5686718bc0380dabcc44c 100644 --- a/oaienv +++ b/oaienv @@ -17,3 +17,6 @@ alias oait='cd $OPENAIR_TARGETS' alias oailte='cd $OPENAIR_TARGETS/RT/USER' alias oais='cd $OPENAIR_TARGETS/SIMU/USER' alias oaiex='cd $OPENAIR_TARGETS/SIMU/EXAMPLES' + +export IIOD_REMOTE=192.168.121.32 + diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index 4b73de6fcc72864fa1a55d7924819dab46cd5e14..8f995e12e345bda05e81f43d4ada30de25d1fba9 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -8118,6 +8118,9 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu, // ulsch->n_DMRS2 = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->cshift; +//printf("Format 0 DCI : ulsch (ue): AbsSubframe %d.%d nrb %d harq_pid %d round %d mcs %d\n",proc->frame_rx%1024,nr_tti_rx,ulsch->harq_processes[harq_pid]->nb_rb, + // harq_pid,ulsch->harq_processes[harq_pid]->round,ulsch->harq_processes[harq_pid]->mcs); + #ifdef UE_DEBUG_TRACE LOG_D(PHY,"Format 0 DCI : ulsch (ue): AbsSubframe %d.%d\n",proc->frame_rx%1024,subframe); diff --git a/openair1/PHY/LTE_TRANSPORT/initial_sync.c b/openair1/PHY/LTE_TRANSPORT/initial_sync.c index 918696968b373ce1830f4abe081fa01505e4e7ae..ab987c4a4f6c8f7173091222ea95c17b038531af 100644 --- a/openair1/PHY/LTE_TRANSPORT/initial_sync.c +++ b/openair1/PHY/LTE_TRANSPORT/initial_sync.c @@ -554,7 +554,7 @@ int initial_sync(PHY_VARS_UE *ue, runmode_t mode) ue->frame_parms.nb_antenna_ports_eNB); #endif -#if defined(OAI_USRP) || defined(EXMIMO) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) +#if defined(OAI_USRP) || defined(EXMIMO) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706) # if DISABLE_LOG_X printf("[UE %d] Frame %d Measured Carrier Frequency %.0f Hz (offset %d Hz)\n", ue->Mod_id, @@ -618,9 +618,11 @@ int initial_sync(PHY_VARS_UE *ue, runmode_t mode) #ifndef OAI_USRP #ifndef OAI_BLADERF #ifndef OAI_LMSSDR +#ifndef OAI_ADRV9371_ZC706 phy_adjust_gain(ue,ue->measurements.rx_power_avg_dB[0],0); #endif #endif +#endif #endif } @@ -629,9 +631,11 @@ int initial_sync(PHY_VARS_UE *ue, runmode_t mode) #ifndef OAI_USRP #ifndef OAI_BLADERF #ifndef OAI_LMSSDR +#ifndef OAI_ADRV9371_ZC706 phy_adjust_gain(ue,dB_fixed(ue->measurements.rssi),0); #endif #endif +#endif #endif } diff --git a/openair1/PHY/LTE_TRANSPORT/prach.c b/openair1/PHY/LTE_TRANSPORT/prach.c index b58aa91636a4d83fb9aa5d6aabfa3a476fc2e884..0c97a307af90be2985c8453290377e7965b07e73 100644 --- a/openair1/PHY/LTE_TRANSPORT/prach.c +++ b/openair1/PHY/LTE_TRANSPORT/prach.c @@ -636,7 +636,7 @@ int32_t generate_prach( PHY_VARS_UE *ue, uint8_t eNB_id, uint8_t subframe, uint1 int i, prach_len; uint16_t first_nonzero_root_idx=0; -#if defined(EXMIMO) || defined(OAI_USRP) +#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_ADRV9371_ZC706) prach_start = (ue->rx_offset+subframe*ue->frame_parms.samples_per_tti-ue->hw_timing_advance-ue->N_TA_offset); #ifdef PRACH_DEBUG LOG_I(PHY,"[UE %d] prach_start %d, rx_offset %d, hw_timing_advance %d, N_TA_offset %d\n", ue->Mod_id, @@ -1042,7 +1042,7 @@ int32_t generate_prach( PHY_VARS_UE *ue, uint8_t eNB_id, uint8_t subframe, uint1 AssertFatal(prach_fmt<4, "prach_fmt4 not fully implemented" ); -#if defined(EXMIMO) || defined(OAI_USRP) +#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_ADRV9371_ZC706) int j; int overflow = prach_start + prach_len - LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*ue->frame_parms.samples_per_tti; LOG_I( PHY, "prach_start=%d, overflow=%d\n", prach_start, overflow ); diff --git a/openair1/PHY/LTE_TRANSPORT/print_stats.c b/openair1/PHY/LTE_TRANSPORT/print_stats.c index 9e328353a4fdd975b26640822813bd4d5a909846..22b1adf3b902631b5263c3111f42215c37ef4a14 100644 --- a/openair1/PHY/LTE_TRANSPORT/print_stats.c +++ b/openair1/PHY/LTE_TRANSPORT/print_stats.c @@ -42,7 +42,7 @@ #endif extern int mac_get_rrc_status(uint8_t Mod_id,uint8_t eNB_flag,uint8_t index); -#if defined(OAI_USRP) || defined(EXMIMO) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) +#if defined(OAI_USRP) || defined(EXMIMO) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706) #include "common_lib.h" extern openair0_config_t openair0_cfg[]; #endif @@ -90,10 +90,10 @@ int dump_ue_stats(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,char* buffer, int length #ifdef EXMIMO len += sprintf(&buffer[len], "[UE PROC] RX Gain %d dB (LNA %d, vga %d dB)\n",ue->rx_total_gain_dB, openair0_cfg[0].rxg_mode[0],(int)openair0_cfg[0].rx_gain[0]); #endif -#if defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) +#if defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706) len += sprintf(&buffer[len], "[UE PROC] RX Gain %d dB\n",ue->rx_total_gain_dB); #endif -#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) +#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706) len += sprintf(&buffer[len], "[UE_PROC] Frequency offset %d Hz, estimated carrier frequency %f Hz\n",ue->common_vars.freq_offset,openair0_cfg[0].rx_freq[0]-ue->common_vars.freq_offset); #endif len += sprintf(&buffer[len], "[UE PROC] UE mode = %s (%d)\n",mode_string[ue->UE_mode[0]],ue->UE_mode[0]); diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index 2635649589643575b027439581079c63b1527ba9..c73e14b28839d7c4b4bdf26307ee9e10263b2c94 100644 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -76,7 +76,7 @@ extern double cpuf; void Msg1_transmitted(module_id_t module_idP,uint8_t CC_id,frame_t frameP, uint8_t eNB_id); void Msg3_transmitted(module_id_t module_idP,uint8_t CC_id,frame_t frameP, uint8_t eNB_id); -#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) +#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706) extern uint32_t downlink_frequency[MAX_NUM_CCs][4]; #endif @@ -158,7 +158,7 @@ void dump_dlsch_SI(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t s exit(-1); } -#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) +#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706) //unsigned int gain_table[31] = {100,112,126,141,158,178,200,224,251,282,316,359,398,447,501,562,631,708,794,891,1000,1122,1258,1412,1585,1778,1995,2239,2512,2818,3162}; /* unsigned int get_tx_amp_prach(int power_dBm, int power_max_dBm, int N_RB_UL) @@ -1202,7 +1202,7 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt int frame_tx = proc->frame_tx; int ulsch_start; int overflow=0; -#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) +#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706) int k,l; int dummy_tx_buffer[frame_parms->samples_per_tti] __attribute__((aligned(16))); #endif @@ -1213,7 +1213,7 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt #endif nsymb = (frame_parms->Ncp == 0) ? 14 : 12; -#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)//this is the EXPRESS MIMO case +#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)//this is the EXPRESS MIMO case ulsch_start = (ue->rx_offset+subframe_tx*frame_parms->samples_per_tti- ue->hw_timing_advance- ue->timing_advance- @@ -1231,7 +1231,7 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt ulsch_start = (frame_parms->samples_per_tti*subframe_tx)-ue->N_TA_offset; //-ue->timing_advance; #endif //else EXMIMO -//#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) +//#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706) if (empty_subframe) { //#if 1 @@ -1279,7 +1279,7 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) { if (frame_parms->Ncp == 1) PHY_ofdm_mod(&ue->common_vars.txdataF[aa][subframe_tx*nsymb*frame_parms->ofdm_symbol_size], -#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) +#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706) dummy_tx_buffer, #else &ue->common_vars.txdata[aa][ulsch_start], @@ -1290,7 +1290,7 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt CYCLIC_PREFIX); else { normal_prefix_mod(&ue->common_vars.txdataF[aa][subframe_tx*nsymb*frame_parms->ofdm_symbol_size], -#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) +#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706) dummy_tx_buffer, #else &ue->common_vars.txdata[aa][ulsch_start], @@ -1308,7 +1308,7 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt &ue->frame_parms); } -#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) +#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706) apply_7_5_kHz(ue,dummy_tx_buffer,0); apply_7_5_kHz(ue,dummy_tx_buffer,1); #else @@ -1317,7 +1317,7 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt #endif -#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) +#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706) overflow = ulsch_start - 9*frame_parms->samples_per_tti; @@ -1822,7 +1822,7 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB } ue->tx_total_RE[subframe_tx] = nb_rb*12; -#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) +#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706) tx_amp = get_tx_amp(ue->tx_power_dBm[subframe_tx], ue->tx_power_max_dBm, ue->frame_parms.N_RB_UL, @@ -1899,7 +1899,7 @@ void ue_srs_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8 Po_SRS = ue->tx_power_max_dBm; } -#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) +#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706) if (ue->mac_enabled==1) { tx_amp = get_tx_amp(Po_SRS, @@ -2182,7 +2182,7 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin ue->tx_power_dBm[subframe_tx] = Po_PUCCH; ue->tx_total_RE[subframe_tx] = 12; -#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) +#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706) tx_amp = get_tx_amp(Po_PUCCH, ue->tx_power_max_dBm, ue->frame_parms.N_RB_UL, @@ -2277,7 +2277,7 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin ue->tx_power_dBm[subframe_tx] = Po_PUCCH; ue->tx_total_RE[subframe_tx] = 12; -#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) +#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706) tx_amp = get_tx_amp(Po_PUCCH, ue->tx_power_max_dBm, ue->frame_parms.N_RB_UL, @@ -2538,9 +2538,11 @@ void ue_measurement_procedures( #ifndef OAI_USRP #ifndef OAI_BLADERF #ifndef OAI_LMSSDR +#ifndef OAI_ADRV9371_ZC706 phy_adjust_gain (ue,dB_fixed(ue->measurements.rssi),0); #endif #endif +#endif #endif VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL, VCD_FUNCTION_OUT); diff --git a/openair2/RRC/LITE/rrc_UE.c b/openair2/RRC/LITE/rrc_UE.c index 3edf230ac2817ca736956c7affd80342980629f4..2a12def7523b7697cedc00b228661202ff95d084 100644 --- a/openair2/RRC/LITE/rrc_UE.c +++ b/openair2/RRC/LITE/rrc_UE.c @@ -788,7 +788,7 @@ rrc_ue_establish_drb( RADIO_ACCESS_BEARER,Rlc_info_um); */ #ifdef PDCP_USE_NETLINK -# if !defined(OAI_NW_DRIVER_TYPE_ETHERNET) && !defined(EXMIMO) && !defined(OAI_USRP) && !defined(OAI_BLADERF) && !defined(ETHERNET) && !defined(LINK_ENB_PDCP_TO_GTPV1U) +# if !defined(OAI_NW_DRIVER_TYPE_ETHERNET) && !defined(EXMIMO) && !defined(OAI_USRP) && !defined(OAI_BLADERF) && !defined(ETHERNET) && !defined(LINK_ENB_PDCP_TO_GTPV1U) && !defined(OAI_ADRV9371_ZC706) ip_addr_offset3 = 0; ip_addr_offset4 = 1; LOG_I(OIP,"[UE %d] trying to bring up the OAI interface oai%d, IP 10.0.%d.%d\n", ue_mod_idP, ip_addr_offset3+ue_mod_idP, diff --git a/openair2/RRC/LITE/rrc_eNB.c b/openair2/RRC/LITE/rrc_eNB.c index 9faa686ef6532afafa413a9c5f4ae633940dcff7..78d32697f39ca3f7785496438e050a5a2a904355 100644 --- a/openair2/RRC/LITE/rrc_eNB.c +++ b/openair2/RRC/LITE/rrc_eNB.c @@ -5401,7 +5401,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( ctxt_pP->module_id, ctxt_pP->frame, (int)DRB_configList->list.array[i]->drb_Identity); #if defined(PDCP_USE_NETLINK) && !defined(LINK_ENB_PDCP_TO_GTPV1U) // can mean also IPV6 since ether -> ipv6 autoconf -# if !defined(OAI_NW_DRIVER_TYPE_ETHERNET) && !defined(EXMIMO) && !defined(OAI_USRP) && !defined(OAI_BLADERF) && !defined(ETHERNET) +# if !defined(OAI_NW_DRIVER_TYPE_ETHERNET) && !defined(EXMIMO) && !defined(OAI_USRP) && !defined(OAI_BLADERF) && !defined(ETHERNET) && !defined(OAI_ADRV9371_ZC706) LOG_I(OIP, "[eNB %d] trying to bring up the OAI interface oai%d\n", ctxt_pP->module_id, ctxt_pP->module_id); diff --git a/targets/ARCH/ADRV9371_ZC706/Makefile b/targets/ARCH/ADRV9371_ZC706/Makefile new file mode 100755 index 0000000000000000000000000000000000000000..5684c7b3bc5cb4047512aece1ac652ff0c111725 --- /dev/null +++ b/targets/ARCH/ADRV9371_ZC706/Makefile @@ -0,0 +1,63 @@ +# Creates shared library + +CC= gcc +CFLAGS+= -DADRV9371_ZC706 -DHWLAT -O0 -g3 -Wall -fmessage-length=0 -fPIC + +DROOT= ./USERSPACE +DIR= $(DROOT)/LIB + +IFLAGS+= -I$(DIR)/ \ + -I$(DROOT)/libini/ \ + -I../COMMON/ \ + -I/usr/include/ + +LDFLAGS+= -L/usr/lib/x86/64-linux-gnu/ \ + -lm -liio -ldl -lriffa + +OUTDIR= ./slib +TARGET= libadrv9371_zc706.so + +SRC= $(DIR)/adrv9371_dump.c \ + $(DIR)/adrv9371_helper.c \ + $(DIR)/adrv9371_self_test.c \ + $(DIR)/adrv9371_zc706_lib.c \ + $(DIR)/adrv9371_zc706_riffa_lib.c \ + $(DIR)/adrv9371_zc706_stats.c \ + $(DIR)/hw_init.c \ + $(DROOT)/libini/libini.c + +OBJ= $(OUTDIR)/adrv9371_dump.o \ + $(OUTDIR)/adrv9371_helper.o \ + $(OUTDIR)/adrv9371_self_test.o \ + $(OUTDIR)/adrv9371_zc706_lib.o \ + $(OUTDIR)/adrv9371_zc706_riffa_lib.o \ + $(OUTDIR)/adrv9371_zc706_stats.o \ + $(OUTDIR)/hw_init.o \ + $(OUTDIR)/libini.o + +all: lib + +dir: + mkdir -p $(OUTDIR) + +env: + set PATH=/usr/lib/:${PATH} + +obj: dir env + $(CC) -c $(CFLAGS) $(IFLAGS) $(SRC) + mv *.o $(OUTDIR) + +lib: dir obj + $(CC) -shared $(OBJ) -o $(OUTDIR)/$(TARGET) $(LDFLAGS) + +# exec: env +# $(CC) $(CFLAGS) $(IFLAGS) main.c $(SRC) -o lib.exe $(LDFLAGS) -lpthread + +.PHONY: clean + +clean: + rm -f $(OUTDIR)/*.o $(OUTDIR)/*~ + +rm: clean + rm -f $(OUTDIR)/$(TARGET) + rmdir $(OUTDIR) \ No newline at end of file diff --git a/targets/ARCH/ADRV9371_ZC706/USERSPACE/PROFILES/ADRV9371-W_test.ini b/targets/ARCH/ADRV9371_ZC706/USERSPACE/PROFILES/ADRV9371-W_test.ini new file mode 100644 index 0000000000000000000000000000000000000000..c1861b2e8dc3314cd3cc1dc5c6e153d01a6c3672 --- /dev/null +++ b/targets/ARCH/ADRV9371_ZC706/USERSPACE/PROFILES/ADRV9371-W_test.ini @@ -0,0 +1,337 @@ +[IIO Oscilloscope] +plugin.DMM.detached=0 +plugin.Debug.detached=0 +plugin.AD9371 Advanced.detached=0 +plugin.AD9371.detached=0 +startup_version_check=0 +test=1 + +[IIO Oscilloscope - Capture Window1] +fru_connect = 1 +test.message = Please ensure:\n • 30.72 MHz -> REF_CLK_IN (0dBm)\n • Rx1 <-> Tx1\n • Rx2 <-> Tx2 +domain=fft +sample_count=400 +fft_size=16384 +fft_avg=8 +fft_pwr_offset=0.000000 +graph_type=Lines +show_grid=1 +enable_auto_scale=1 +x_axis_min=-67.583626 +x_axis_max=67.576126 +y_axis_min=-130 +y_axis_max=3 +show_capture_options = 1 + +axi-ad9371-rx-obs-hpc.expanded=1 +axi-ad9371-rx-obs-hpc.active=0 +axi-ad9371-rx-obs-hpc.trigger_enabled=0 +axi-ad9371-rx-obs-hpc.voltage0_i.enabled=0 +axi-ad9371-rx-obs-hpc.voltage0_q.enabled=0 + +axi-ad9371-rx-hpc.expanded=1 +axi-ad9371-rx-hpc.active=1 +axi-ad9371-rx-hpc.voltage0_i.enabled=1 +axi-ad9371-rx-hpc.voltage0_q.enabled=1 +axi-ad9371-rx-hpc.voltage1_i.enabled=0 +axi-ad9371-rx-hpc.voltage1_q.enabled=0 + +marker_type = Single Tone Markers +marker.0 = 9525 +marker.1 = 8192 +marker.2 = 10859 +marker.3 = 12193 +marker.4 = 13526 +marker.5 = 14859 +capture_started=0 + +[DMM] +device_list = ad7291 0 +device_list = ad9371-phy 0 +device_list = xadc 0 +running = No + +# temp between 20C and 55C (in 0.25C units) +test.ad7291.in_temp0_raw.int = 80 220 + +# See the production testing wiki docs [1] for how these values are calculated. +# [1]: (https://wiki.analog.com/resources/eval/user-guides/ad-fmcomms2-ebz/testing#voltage) + +# scale = 0.610351562 +# All nominal voltages +/- 2.5% + +# 0 INPUT_VOLTAGE 12V - V(Drop Diode) 56/10 +test.ad7291.in_voltage0_raw.int = 2710 2850 + +# 1 VOUT2_1V3_DIG 1 +test.ad7291.in_voltage1_raw.int = 2077 2183 + +# 2 VDD_IF 10/10 +test.ad7291.in_voltage2_raw.int = 1997 2099 + +# 3 VOUT3_3V3 10/10 +test.ad7291.in_voltage3_raw.int = 2636 2770 + +# 5 VOUT4_1V8 1 +test.ad7291.in_voltage5_raw.int = 2875 3023 + +# 7 VOUT1_1V3_ANLG 1 +test.ad7291.in_voltage7_raw.int = 2077 2183 + + +# Test AD9528 lock status - Requires 30.720 MHz reference clock! +test.ad9528-1.pll1_reference_clk_a_present.int = 1 1 +test.ad9528-1.pll1_locked.int = 1 1 +test.ad9528-1.pll2_locked.int = 1 1 + + +[AD9371] +ad9371-phy.in_voltage2_rf_port_select = INTERNALCALS +ad9371-phy.in_voltage2_temp_comp_gain = 0.00 dB +ad9371-phy.out_altvoltage1_TX_LO_frequency = 2500000000 +ad9371-phy.out_altvoltage2_RX_SN_LO_frequency = 2600000000 +ad9371-phy.out_voltage1_hardwaregain = -10.000000 dB +ad9371-phy.out_voltage1_lo_leakage_tracking_en = 1 +ad9371-phy.out_voltage1_quadrature_tracking_en = 1 +ad9371-phy.in_voltage0_gain_control_mode = automatic +ad9371-phy.in_voltage0_quadrature_tracking_en = 1 +ad9371-phy.in_voltage0_temp_comp_gain = 0.00 dB +ad9371-phy.in_voltage1_quadrature_tracking_en = 1 +ad9371-phy.in_voltage1_temp_comp_gain = 0.00 dB +ad9371-phy.in_voltage1_gain_control_mode = automatic +ad9371-phy.out_altvoltage0_RX_LO_frequency = 2600000000 +ad9371-phy.out_voltage0_lo_leakage_tracking_en = 1 +ad9371-phy.out_voltage0_hardwaregain = -10.000000 dB +ad9371-phy.out_voltage0_quadrature_tracking_en = 1 +ad9371-phy.ensm_mode = radio_on +axi-ad9371-tx-hpc.out_altvoltage0_TX1_I_F1_phase = 90000 +axi-ad9371-tx-hpc.out_altvoltage0_TX1_I_F1_scale = 0.251160 +axi-ad9371-tx-hpc.out_altvoltage0_TX1_I_F1_frequency = 10001402 +axi-ad9371-tx-hpc.out_altvoltage0_TX1_I_F1_raw = 1 +axi-ad9371-tx-hpc.out_altvoltage5_TX2_I_F2_phase = 90000 +axi-ad9371-tx-hpc.out_altvoltage5_TX2_I_F2_scale = 0.000000 +axi-ad9371-tx-hpc.out_altvoltage5_TX2_I_F2_raw = 1 +axi-ad9371-tx-hpc.out_altvoltage5_TX2_I_F2_frequency = 1001265 +axi-ad9371-tx-hpc.out_altvoltage4_TX2_I_F1_frequency = 10001402 +axi-ad9371-tx-hpc.out_altvoltage4_TX2_I_F1_phase = 90000 +axi-ad9371-tx-hpc.out_altvoltage4_TX2_I_F1_scale = 0.251160 +axi-ad9371-tx-hpc.out_altvoltage4_TX2_I_F1_raw = 1 +axi-ad9371-tx-hpc.out_altvoltage6_TX2_Q_F1_frequency = 10001402 +axi-ad9371-tx-hpc.out_altvoltage6_TX2_Q_F1_raw = 1 +axi-ad9371-tx-hpc.out_altvoltage6_TX2_Q_F1_phase = 0 +axi-ad9371-tx-hpc.out_altvoltage6_TX2_Q_F1_scale = 0.251160 +axi-ad9371-tx-hpc.out_altvoltage3_TX1_Q_F2_raw = 1 +axi-ad9371-tx-hpc.out_altvoltage3_TX1_Q_F2_phase = 0 +axi-ad9371-tx-hpc.out_altvoltage3_TX1_Q_F2_scale = 0.000000 +axi-ad9371-tx-hpc.out_altvoltage3_TX1_Q_F2_frequency = 40001860 +axi-ad9371-tx-hpc.out_altvoltage7_TX2_Q_F2_raw = 1 +axi-ad9371-tx-hpc.out_altvoltage7_TX2_Q_F2_phase = 0 +axi-ad9371-tx-hpc.out_altvoltage7_TX2_Q_F2_scale = 0.000000 +axi-ad9371-tx-hpc.out_altvoltage7_TX2_Q_F2_frequency = 1001265 +axi-ad9371-tx-hpc.out_altvoltage2_TX1_Q_F1_raw = 1 +axi-ad9371-tx-hpc.out_altvoltage2_TX1_Q_F1_phase = 0 +axi-ad9371-tx-hpc.out_altvoltage2_TX1_Q_F1_scale = 0.251160 +axi-ad9371-tx-hpc.out_altvoltage2_TX1_Q_F1_frequency = 10001402 +axi-ad9371-tx-hpc.out_altvoltage1_TX1_I_F2_frequency = 40001860 +axi-ad9371-tx-hpc.out_altvoltage1_TX1_I_F2_raw = 1 +axi-ad9371-tx-hpc.out_altvoltage1_TX1_I_F2_phase = 90000 +axi-ad9371-tx-hpc.out_altvoltage1_TX1_I_F2_scale = 0.000000 +dds_mode_tx1 = 0 +dds_mode_tx2 = 0 +SYNC_RELOAD = 1 + +# test receiver at 1GHz to 5 GHz +# SEQ FIRST INCREMENT LAST +<SEQ> i 1000000000 5000000000 5000000000 + +[IIO Oscilloscope - Capture Window1] +# wait for device to settle +marker_type = Peak Markers +capture_started = 0 +cycle = 1000 +axi-ad9371-rx-hpc.voltage0_i.enabled=1 +axi-ad9371-rx-hpc.voltage0_q.enabled=1 +axi-ad9371-rx-hpc.voltage1_i.enabled=0 +axi-ad9371-rx-hpc.voltage1_q.enabled=0 +cycle = 1000 + +[AD9371] +ad9371-phy.out_altvoltage1_TX_LO_frequency = <i> +ad9371-phy.out_altvoltage2_RX_SN_LO_frequency = {{<i>} + {100000000}} +ad9371-phy.out_altvoltage0_RX_LO_frequency = {{<i>} + {100000000}} +dds_mode_tx1 = 0 +dds_mode_tx2 = 0 +SYNC_RELOAD = 1 + +[IIO Oscilloscope - Capture Window1] +# wait for device to settle +capture_started = 1 +cycle = 3000 + +[AD9371] +# channels should be off, so RSSI should be low +test.ad9371-phy.in_voltage0_rssi.int = 44 45 +test.ad9371-phy.in_voltage1_rssi.int = 44 45 + +# and gain is high +test.ad9371-phy.in_voltage0_hardwaregain.double = 30.0 31.0 +test.ad9371-phy.in_voltage0_hardwaregain.double = 30.0 31.0 + +# set Tx and Rx to be the same +ad9371-phy.out_altvoltage0_RX_LO_frequency = <i> +dds_mode_tx1 = 1 +dds_mode_tx2 = 1 +SYNC_RELOAD = 1 + +[IIO Oscilloscope - Capture Window1] +# wait for device to settle +marker_type = Single Tone Markers +cycle = 3000 + +[AD9371] + +ad9371-phy.out_voltage0_hardwaregain = 0.000000 dB +ad9371-phy.out_voltage1_hardwaregain = 0.000000 dB + +# channels should be on, so RSSI should be high +test.ad9371-phy.in_voltage0_rssi.int = 3 12 +test.ad9371-phy.in_voltage1_rssi.int = 3 12 + +# and gain is low +test.ad9371-phy.in_voltage0_hardwaregain.double = 15.0 29.0 +test.ad9371-phy.in_voltage0_hardwaregain.double = 15.0 29.0 + + + +[IIO Oscilloscope - Capture Window1] +cycle = 1000 +capture_started = 1 +cycle = 3000 +save_png = ADRV9371_rx1_<i>.png +save_markers = markers.log + +#look at the markers - Fundamental +test.marker.0 = -12.0 -4.0 +# DC +test.marker.1 = -100.0 -60.0 +# 2st Harmonic +test.marker.2 = -110.0 -75.0 +# 3nd Harmonic +test.marker.3 = -110.0 -75.0 +# 4th Harmonic +test.marker.4 = -110.0 -75.0 +# 4th Harmonic +test.marker.5 = -110.0 -65.0 + +capture_started = 0 +cycle = 1000 + +axi-ad9371-rx-hpc.voltage0_i.enabled=0 +axi-ad9371-rx-hpc.voltage0_q.enabled=0 +axi-ad9371-rx-hpc.voltage1_i.enabled=1 +axi-ad9371-rx-hpc.voltage1_q.enabled=1 + +cycle = 1000 +capture_started = 1 +cycle = 3000 +save_png = ADRV9371_rx2_<i>.png +save_markers = markers.log + +#look at the markers - Fundamental +test.marker.0 = -12.0 -4.0 +# DC +test.marker.1 = -100.0 -60.0 +# 2st Harmonic +test.marker.2 = -110.0 -75.0 +# 3nd Harmonic +test.marker.3 = -110.0 -75.0 +# 4th Harmonic +test.marker.4 = -110.0 -75.0 +# 4th Harmonic +test.marker.5 = -110.0 -65.0 + +</SEQ> + +[IIO Oscilloscope - Capture Window1] +capture_started = 0 +test.message = Please ensure:\n • ORX1 <-> Tx1\n • ORX22 <-> Tx2 + +axi-ad9371-rx-hpc.expanded=1 +axi-ad9371-rx-hpc.active=0 +axi-ad9371-rx-hpc.voltage0_i.enabled=0 +axi-ad9371-rx-hpc.voltage0_q.enabled=0 +axi-ad9371-rx-hpc.voltage1_i.enabled=0 +axi-ad9371-rx-hpc.voltage1_q.enabled=0 + +axi-ad9371-rx-obs-hpc.expanded=1 +axi-ad9371-rx-obs-hpc.active=1 +axi-ad9371-rx-obs-hpc.voltage0_i.enabled=1 +axi-ad9371-rx-obs-hpc.voltage0_q.enabled=1 +cycle = 1000 + +# test observer path at 1GHz to 5 GHz +# SEQ FIRST INCREMENT LAST +<SEQ> i 1000000000 1000000000 5000000000 + +[AD9371] +# set Tx and Rx to be the same +ad9371-phy.out_altvoltage1_TX_LO_frequency = <i> +ad9371-phy.out_altvoltage2_RX_SN_LO_frequency = {{<i>} + {1000000}} +ad9371-phy.out_altvoltage0_RX_LO_frequency = <i> +dds_mode_tx1 = 1 +dds_mode_tx2 = 1 +ad9371-phy.out_voltage0_hardwaregain = -10.000000 dB +ad9371-phy.out_voltage1_hardwaregain = -10.000000 dB +ad9371-phy.in_voltage2_rf_port_select = ORX1_TX_LO +ad9371-phy.in_voltage2_gain_control_mode = manual +ad9371-phy.in_voltage2_hardwaregain = 18.000000 dB + +[IIO Oscilloscope - Capture Window1] +capture_started = 1 +cycle = 3000 +save_png = ADRV9371_ob1_<i>.png +save_markers = markers.log + +#look at the markers - Fundamental +test.marker.0 = -15.0 -5.0 +# DC +test.marker.1 = -100.0 -75.0 +# 2st Harmonic +test.marker.2 = -110.0 -75.0 +# 3nd Harmonic +test.marker.3 = -110.0 -75.0 +# 4th Harmonic +test.marker.4 = -110.0 -75.0 +# 4th Harmonic +test.marker.5 = -110.0 -65.0 + +[AD9371] + +ad9371-phy.in_voltage2_rf_port_select = ORX2_TX_LO + + +[IIO Oscilloscope - Capture Window1] +cycle = 1000 +capture_started = 1 +cycle = 3000 +save_png = ADRV9371_ob2_<i>.png +save_markers = markers.log + +#look at the markers - Fundamental +test.marker.0 = -15.0 -4.0 +# DC +test.marker.1 = -100.0 -75.0 +# 2st Harmonic +test.marker.2 = -110.0 -75.0 +# 3nd Harmonic +test.marker.3 = -110.0 -75.0 +# 4th Harmonic +test.marker.4 = -110.0 -75.0 +# 4th Harmonic +test.marker.5 = -110.0 -65.0 + +</SEQ> + +[IIO Oscilloscope - Capture Window1] +test.message = All tests passed - Ship it +quit = 1 diff --git a/targets/ARCH/ADRV9371_ZC706/USERSPACE/PROFILES/profile1-osc.ini b/targets/ARCH/ADRV9371_ZC706/USERSPACE/PROFILES/profile1-osc.ini new file mode 100644 index 0000000000000000000000000000000000000000..4282cfffdd1230fd5c9f8f44f87a04a434b8c2b6 --- /dev/null +++ b/targets/ARCH/ADRV9371_ZC706/USERSPACE/PROFILES/profile1-osc.ini @@ -0,0 +1,85 @@ +[AD9371] +ad9371-phy.in_voltage2_rf_port_select = OFF +ad9371-phy.in_voltage2_hardwaregain = -156.000000 dB +ad9371-phy.in_voltage2_temp_comp_gain = 0.00 dB +ad9371-phy.in_voltage_rf_port_select_available = OFF INTERNALCALS OBS_SNIFFER SN_A SN_B SN_C ORX1_TX_LO ORX2_TX_LO ORX1_SN_LO ORX2_SN_LO +ad9371-phy.out_voltage0_lo_leakage_tracking_en = 0 +ad9371-phy.out_voltage0_hardwaregain = -10.000000 dB +ad9371-phy.out_voltage0_quadrature_tracking_en = 1 +ad9371-phy.out_voltage1_hardwaregain = -10.000000 dB +ad9371-phy.out_voltage1_lo_leakage_tracking_en = 0 +ad9371-phy.out_voltage1_quadrature_tracking_en = 1 +ad9371-phy.in_voltage_rf_port_select_available = OFF INTERNALCALS OBS_SNIFFER SN_A SN_B SN_C ORX1_TX_LO ORX2_TX_LO ORX1_SN_LO ORX2_SN_LO +ad9371-phy.out_altvoltage1_TX_LO_frequency = 2685000000 +ad9371-phy.out_altvoltage2_RX_SN_LO_frequency = 2565000000 +ad9371-phy.in_voltage_rf_port_select_available = OFF INTERNALCALS OBS_SNIFFER SN_A SN_B SN_C ORX1_TX_LO ORX2_TX_LO ORX1_SN_LO ORX2_SN_LO +ad9371-phy.in_voltage_rf_port_select_available = OFF INTERNALCALS OBS_SNIFFER SN_A SN_B SN_C ORX1_TX_LO ORX2_TX_LO ORX1_SN_LO ORX2_SN_LO +ad9371-phy.in_voltage_rf_port_select_available = OFF INTERNALCALS OBS_SNIFFER SN_A SN_B SN_C ORX1_TX_LO ORX2_TX_LO ORX1_SN_LO ORX2_SN_LO +ad9371-phy.in_voltage0_gain_control_mode = automatic +ad9371-phy.in_voltage0_quadrature_tracking_en = 1 +ad9371-phy.in_voltage0_hardwaregain = 30.000000 dB +ad9371-phy.in_voltage0_temp_comp_gain = 0.00 dB +ad9371-phy.in_voltage_rf_port_select_available = OFF INTERNALCALS OBS_SNIFFER SN_A SN_B SN_C ORX1_TX_LO ORX2_TX_LO ORX1_SN_LO ORX2_SN_LO +ad9371-phy.in_voltage1_quadrature_tracking_en = 1 +ad9371-phy.in_voltage1_hardwaregain = 30.000000 dB +ad9371-phy.in_voltage1_temp_comp_gain = 0.00 dB +ad9371-phy.in_voltage1_gain_control_mode = automatic +ad9371-phy.in_voltage_rf_port_select_available = OFF INTERNALCALS OBS_SNIFFER SN_A SN_B SN_C ORX1_TX_LO ORX2_TX_LO ORX1_SN_LO ORX2_SN_LO +ad9371-phy.out_altvoltage0_RX_LO_frequency = 2565000000 +ad9371-phy.calibrate_rx_qec_en = 0 +ad9371-phy.calibrate_tx_lol_en = 0 +ad9371-phy.calibrate_vswr_en = 0 +ad9371-phy.calibrate_tx_qec_en = 0 +ad9371-phy.calibrate_clgc_en = 0 +ad9371-phy.ensm_mode = radio_on +ad9371-phy.calibrate_tx_lol_ext_en = 0 +ad9371-phy.calibrate_dpd_en = 0 +axi-ad9371-tx-hpc.out_altvoltage0_TX1_I_F1_phase = 90000 +axi-ad9371-tx-hpc.out_altvoltage0_TX1_I_F1_scale = 0.501160 +axi-ad9371-tx-hpc.out_altvoltage0_TX1_I_F1_frequency = 1999718 +axi-ad9371-tx-hpc.out_altvoltage0_TX1_I_F1_raw = 1 +axi-ad9371-tx-hpc.out_altvoltage5_TX2_I_F2_phase = 90000 +axi-ad9371-tx-hpc.out_altvoltage5_TX2_I_F2_scale = 0.000000 +axi-ad9371-tx-hpc.out_altvoltage5_TX2_I_F2_raw = 1 +axi-ad9371-tx-hpc.out_altvoltage5_TX2_I_F2_frequency = 1000327 +axi-ad9371-tx-hpc.out_altvoltage4_TX2_I_F1_frequency = 7999809 +axi-ad9371-tx-hpc.out_altvoltage4_TX2_I_F1_phase = 90000 +axi-ad9371-tx-hpc.out_altvoltage4_TX2_I_F1_scale = 0.251160 +axi-ad9371-tx-hpc.out_altvoltage4_TX2_I_F1_raw = 1 +axi-ad9371-tx-hpc.out_altvoltage6_TX2_Q_F1_frequency = 7999809 +axi-ad9371-tx-hpc.out_altvoltage6_TX2_Q_F1_raw = 1 +axi-ad9371-tx-hpc.out_altvoltage6_TX2_Q_F1_phase = 0 +axi-ad9371-tx-hpc.out_altvoltage6_TX2_Q_F1_scale = 0.251160 +axi-ad9371-tx-hpc.out_altvoltage3_TX1_Q_F2_raw = 1 +axi-ad9371-tx-hpc.out_altvoltage3_TX1_Q_F2_phase = 0 +axi-ad9371-tx-hpc.out_altvoltage3_TX1_Q_F2_scale = 0.000000 +axi-ad9371-tx-hpc.out_altvoltage3_TX1_Q_F2_frequency = 19998117 +axi-ad9371-tx-hpc.out_altvoltage7_TX2_Q_F2_raw = 1 +axi-ad9371-tx-hpc.out_altvoltage7_TX2_Q_F2_phase = 0 +axi-ad9371-tx-hpc.out_altvoltage7_TX2_Q_F2_scale = 0.000000 +axi-ad9371-tx-hpc.out_altvoltage7_TX2_Q_F2_frequency = 1000327 +axi-ad9371-tx-hpc.out_altvoltage2_TX1_Q_F1_raw = 1 +axi-ad9371-tx-hpc.out_altvoltage2_TX1_Q_F1_phase = 0 +axi-ad9371-tx-hpc.out_altvoltage2_TX1_Q_F1_scale = 0.501160 +axi-ad9371-tx-hpc.out_altvoltage2_TX1_Q_F1_frequency = 1999718 +axi-ad9371-tx-hpc.out_altvoltage1_TX1_I_F2_frequency = 19998117 +axi-ad9371-tx-hpc.out_altvoltage1_TX1_I_F2_raw = 1 +axi-ad9371-tx-hpc.out_altvoltage1_TX1_I_F2_phase = 90000 +axi-ad9371-tx-hpc.out_altvoltage1_TX1_I_F2_scale = 0.000000 +load_myk_profile_file = /targets/ARCH/ADRV9371_ZC706/USERSPACE/PROFILES/profile_rx30_Tx60_syr.txt +dds_mode_tx1 = 1 +dds_mode_tx2 = 1 +dac_buf_filename = /usr/local/lib/osc/waveforms/LTE20.mat +tx_channel_0 = 1 +tx_channel_1 = 1 +tx_channel_2 = 0 +tx_channel_3 = 0 +global_settings_show = 1 +tx_show = 1 +rx_show = 1 +obs_show = 1 +fpga_show = 1 + +[ADRV9371_ZC706] +debug_mode = 0 +interpolation_decimation_factor = 2 diff --git a/targets/ARCH/ADRV9371_ZC706/USERSPACE/PROFILES/profile_rx30_Tx60_syr.txt b/targets/ARCH/ADRV9371_ZC706/USERSPACE/PROFILES/profile_rx30_Tx60_syr.txt new file mode 100644 index 0000000000000000000000000000000000000000..ac20ab2663cf34f2c4ae2f91c02152c5e15b8c92 --- /dev/null +++ b/targets/ARCH/ADRV9371_ZC706/USERSPACE/PROFILES/profile_rx30_Tx60_syr.txt @@ -0,0 +1,285 @@ +<profile AD9371 version=0 name=Rx 20, IQrate 30.720> + <clocks> + <deviceClock_kHz=122880> + <clkPllVcoFreq_kHz=9830400> + <clkPllVcoDiv=2> + <clkPllHsDiv=4> + </clocks> + + <rx> + <adcDiv=1> + <rxFirDecimation=4> + <rxDec5Decimation=5> + <enHighRejDec5=1> + <rhb1Decimation=2> + <iqRate_kHz=30720> + <rfBandwidth_Hz=20000000> + <rxBbf3dBCorner_kHz=20000> + + <filter FIR gain=-6 num=72> + 0 + 2 + 4 + 3 + -4 + -14 + -21 + -12 + 17 + 56 + 73 + 39 + -53 + -159 + -198 + -101 + 129 + 377 + 457 + 229 + -274 + -793 + -951 + -482 + 527 + 1564 + 1899 + 1011 + -978 + -3154 + -4109 + -2611 + 1669 + 7795 + 13807 + 17524 + 17524 + 13807 + 7795 + 1669 + -2611 + -4109 + -3154 + -978 + 1011 + 1899 + 1564 + 527 + -482 + -951 + -793 + -274 + 229 + 457 + 377 + 129 + -101 + -198 + -159 + -53 + 39 + 73 + 56 + 17 + -12 + -21 + -14 + -4 + 3 + 4 + 2 + 0 + </filter> + + <adc-profile num=16> + 599 + 357 + 201 + 98 + 1280 + 112 + 1505 + 53 + 1331 + 21 + 820 + 40 + 48 + 40 + 23 + 191 + </adc-profile> + </rx> + + <obs> + <adcDiv=1> + <rxFirDecimation=2> + <rxDec5Decimation=5> + <enHighRejDec5=1> + <rhb1Decimation=2> + <iqRate_kHz=61440> + <rfBandwidth_Hz=50000000> + <rxBbf3dBCorner_kHz=25000> + + <filter FIR gain=0 num=72> + 0 + -1 + 1 + 2 + -2 + -6 + 6 + 12 + -13 + -24 + 25 + 43 + -45 + -73 + 77 + 118 + -124 + -183 + 193 + 274 + -289 + -402 + 423 + 579 + -607 + -826 + 866 + 1187 + -1244 + -1759 + 1842 + 2818 + -2970 + -5815 + 4337 + 18436 + 18436 + 4337 + -5815 + -2970 + 2818 + 1842 + -1759 + -1244 + 1187 + 866 + -826 + -607 + 579 + 423 + -402 + -289 + 274 + 193 + -183 + -124 + 118 + 77 + -73 + -45 + 43 + 25 + -24 + -13 + 12 + 6 + -6 + -2 + 2 + 1 + -1 + 0 + </filter> + + <adc-profile num=16> + 596 + 358 + 201 + 98 + 1280 + 134 + 1509 + 64 + 1329 + 25 + 818 + 39 + 48 + 40 + 23 + 190 + </adc-profile> + + <lpbk-adc-profile num=16> + 599 + 357 + 201 + 98 + 1280 + 112 + 1505 + 53 + 1331 + 21 + 820 + 40 + 48 + 40 + 23 + 191 + </lpbk-adc-profile> + </obs> + + <tx> + <dacDiv=2.5> + <txFirInterpolation=2> + <thb1Interpolation=2> + <thb2Interpolation=2> + <txInputHbInterpolation=1> + <iqRate_kHz=61440> + <primarySigBandwidth_Hz=20000000> + <rfBandwidth_Hz=50000000> + <txDac3dBCorner_kHz=92000> + <txBbf3dBCorner_kHz=25000> + + <filter FIR gain=0 num=32> + -118 + -122 + 242 + 240 + -429 + -499 + 730 + 900 + -1154 + -1615 + 1742 + 2957 + -2322 + -5354 + 3885 + 17211 + 17211 + 3885 + -5354 + -2322 + 2957 + 1742 + -1615 + -1154 + 900 + 730 + -499 + -429 + 240 + 242 + -122 + -118 + </filter> + </tx> +</profile> diff --git a/targets/ARCH/ADRV9371_ZC706/USERSPACE/PROFILES/ue.band7.tm1.PRB100.adrv9371-zc706.ini b/targets/ARCH/ADRV9371_ZC706/USERSPACE/PROFILES/ue.band7.tm1.PRB100.adrv9371-zc706.ini new file mode 100644 index 0000000000000000000000000000000000000000..34a98d4a7711f30ee9bd1e438f3b0a824a930d5a --- /dev/null +++ b/targets/ARCH/ADRV9371_ZC706/USERSPACE/PROFILES/ue.band7.tm1.PRB100.adrv9371-zc706.ini @@ -0,0 +1,89 @@ +[AD9371] +ad9371-phy.in_voltage2_rf_port_select = OFF +ad9371-phy.in_voltage2_hardwaregain = -156.000000 dB +ad9371-phy.in_voltage2_temp_comp_gain = 0.00 dB +ad9371-phy.in_voltage_rf_port_select_available = OFF INTERNALCALS OBS_SNIFFER SN_A SN_B SN_C ORX1_TX_LO ORX2_TX_LO ORX1_SN_LO ORX2_SN_LO +ad9371-phy.out_voltage0_lo_leakage_tracking_en = 0 +ad9371-phy.out_voltage0_hardwaregain = 0.000000 dB +ad9371-phy.out_voltage0_quadrature_tracking_en = 1 +ad9371-phy.out_voltage1_hardwaregain = 0.000000 dB +ad9371-phy.out_voltage1_lo_leakage_tracking_en = 0 +ad9371-phy.out_voltage1_quadrature_tracking_en = 1 +ad9371-phy.in_voltage_rf_port_select_available = OFF INTERNALCALS OBS_SNIFFER SN_A SN_B SN_C ORX1_TX_LO ORX2_TX_LO ORX1_SN_LO ORX2_SN_LO +ad9371-phy.out_altvoltage1_TX_LO_frequency = 2560000000 +ad9371-phy.out_altvoltage2_RX_SN_LO_frequency = 2680000000 +ad9371-phy.in_voltage_rf_port_select_available = OFF INTERNALCALS OBS_SNIFFER SN_A SN_B SN_C ORX1_TX_LO ORX2_TX_LO ORX1_SN_LO ORX2_SN_LO +ad9371-phy.in_voltage_rf_port_select_available = OFF INTERNALCALS OBS_SNIFFER SN_A SN_B SN_C ORX1_TX_LO ORX2_TX_LO ORX1_SN_LO ORX2_SN_LO +ad9371-phy.in_voltage_rf_port_select_available = OFF INTERNALCALS OBS_SNIFFER SN_A SN_B SN_C ORX1_TX_LO ORX2_TX_LO ORX1_SN_LO ORX2_SN_LO +ad9371-phy.in_voltage0_gain_control_mode = manual +ad9371-phy.in_voltage0_quadrature_tracking_en = 1 +ad9371-phy.in_voltage0_hardwaregain = 25.000000 dB +ad9371-phy.in_voltage0_temp_comp_gain = 0.00 dB +ad9371-phy.in_voltage_rf_port_select_available = OFF INTERNALCALS OBS_SNIFFER SN_A SN_B SN_C ORX1_TX_LO ORX2_TX_LO ORX1_SN_LO ORX2_SN_LO +ad9371-phy.in_voltage1_quadrature_tracking_en = 1 +ad9371-phy.in_voltage1_hardwaregain = 25.000000 dB +ad9371-phy.in_voltage1_temp_comp_gain = 0.00 dB +ad9371-phy.in_voltage1_gain_control_mode = manual +ad9371-phy.in_voltage_rf_port_select_available = OFF INTERNALCALS OBS_SNIFFER SN_A SN_B SN_C ORX1_TX_LO ORX2_TX_LO ORX1_SN_LO ORX2_SN_LO +ad9371-phy.out_altvoltage0_RX_LO_frequency = 2680000000 +ad9371-phy.calibrate_rx_qec_en = 0 +ad9371-phy.calibrate_tx_lol_en = 0 +ad9371-phy.calibrate_vswr_en = 0 +ad9371-phy.calibrate_tx_qec_en = 0 +ad9371-phy.calibrate_clgc_en = 0 +ad9371-phy.ensm_mode = radio_on +ad9371-phy.calibrate_tx_lol_ext_en = 0 +ad9371-phy.calibrate_dpd_en = 0 +axi-ad9371-tx-hpc.out_altvoltage0_TX1_I_F1_phase = 90000 +axi-ad9371-tx-hpc.out_altvoltage0_TX1_I_F1_scale = 0.501160 +axi-ad9371-tx-hpc.out_altvoltage0_TX1_I_F1_frequency = 1999718 +axi-ad9371-tx-hpc.out_altvoltage0_TX1_I_F1_raw = 1 +axi-ad9371-tx-hpc.out_altvoltage5_TX2_I_F2_phase = 90000 +axi-ad9371-tx-hpc.out_altvoltage5_TX2_I_F2_scale = 0.000000 +axi-ad9371-tx-hpc.out_altvoltage5_TX2_I_F2_raw = 1 +axi-ad9371-tx-hpc.out_altvoltage5_TX2_I_F2_frequency = 1000327 +axi-ad9371-tx-hpc.out_altvoltage4_TX2_I_F1_frequency = 7999809 +axi-ad9371-tx-hpc.out_altvoltage4_TX2_I_F1_phase = 90000 +axi-ad9371-tx-hpc.out_altvoltage4_TX2_I_F1_scale = 0.251160 +axi-ad9371-tx-hpc.out_altvoltage4_TX2_I_F1_raw = 1 +axi-ad9371-tx-hpc.out_altvoltage6_TX2_Q_F1_frequency = 7999809 +axi-ad9371-tx-hpc.out_altvoltage6_TX2_Q_F1_raw = 1 +axi-ad9371-tx-hpc.out_altvoltage6_TX2_Q_F1_phase = 0 +axi-ad9371-tx-hpc.out_altvoltage6_TX2_Q_F1_scale = 0.251160 +axi-ad9371-tx-hpc.out_altvoltage3_TX1_Q_F2_raw = 1 +axi-ad9371-tx-hpc.out_altvoltage3_TX1_Q_F2_phase = 0 +axi-ad9371-tx-hpc.out_altvoltage3_TX1_Q_F2_scale = 0.000000 +axi-ad9371-tx-hpc.out_altvoltage3_TX1_Q_F2_frequency = 19998117 +axi-ad9371-tx-hpc.out_altvoltage7_TX2_Q_F2_raw = 1 +axi-ad9371-tx-hpc.out_altvoltage7_TX2_Q_F2_phase = 0 +axi-ad9371-tx-hpc.out_altvoltage7_TX2_Q_F2_scale = 0.000000 +axi-ad9371-tx-hpc.out_altvoltage7_TX2_Q_F2_frequency = 1000327 +axi-ad9371-tx-hpc.out_altvoltage2_TX1_Q_F1_raw = 1 +axi-ad9371-tx-hpc.out_altvoltage2_TX1_Q_F1_phase = 0 +axi-ad9371-tx-hpc.out_altvoltage2_TX1_Q_F1_scale = 0.501160 +axi-ad9371-tx-hpc.out_altvoltage2_TX1_Q_F1_frequency = 1999718 +axi-ad9371-tx-hpc.out_altvoltage1_TX1_I_F2_frequency = 19998117 +axi-ad9371-tx-hpc.out_altvoltage1_TX1_I_F2_raw = 1 +axi-ad9371-tx-hpc.out_altvoltage1_TX1_I_F2_phase = 90000 +axi-ad9371-tx-hpc.out_altvoltage1_TX1_I_F2_scale = 0.000000 +load_myk_profile_file = /targets/ARCH/ADRV9371_ZC706/USERSPACE/PROFILES/profile20MHz.txt +dds_mode_tx1 = 1 +dds_mode_tx2 = 1 +dac_buf_filename = /usr/local/lib/osc/waveforms/LTE20.mat +tx_channel_0 = 1 +tx_channel_1 = 1 +tx_channel_2 = 0 +tx_channel_3 = 0 +global_settings_show = 1 +tx_show = 1 +rx_show = 1 +obs_show = 1 +fpga_show = 1 + +[ADRV9371_ZC706] +# NO_DEBUG=0; DEBUG=1 +debug_mode = 0 +# 20MHz 40MHz 80MHz=1; 10MHz=2; 5MHz=4 +interpolation_decimation_factor = 1 +# is taken into account only if "ad9371-phy.in_voltage0_gain_control_mode = manual" +rx_gain_offset = 69 diff --git a/targets/ARCH/ADRV9371_ZC706/USERSPACE/PROFILES/ue.band7.tm1.PRB100.adrv9371-zc706_HWgain15dB.ini b/targets/ARCH/ADRV9371_ZC706/USERSPACE/PROFILES/ue.band7.tm1.PRB100.adrv9371-zc706_HWgain15dB.ini new file mode 100644 index 0000000000000000000000000000000000000000..e12de4edbe6509a0e31466fd8e7cd514172d412b --- /dev/null +++ b/targets/ARCH/ADRV9371_ZC706/USERSPACE/PROFILES/ue.band7.tm1.PRB100.adrv9371-zc706_HWgain15dB.ini @@ -0,0 +1,89 @@ +[AD9371] +ad9371-phy.in_voltage2_rf_port_select = OFF +ad9371-phy.in_voltage2_hardwaregain = -156.000000 dB +ad9371-phy.in_voltage2_temp_comp_gain = 0.00 dB +ad9371-phy.in_voltage_rf_port_select_available = OFF INTERNALCALS OBS_SNIFFER SN_A SN_B SN_C ORX1_TX_LO ORX2_TX_LO ORX1_SN_LO ORX2_SN_LO +ad9371-phy.out_voltage0_lo_leakage_tracking_en = 0 +ad9371-phy.out_voltage0_hardwaregain = 0.000000 dB +ad9371-phy.out_voltage0_quadrature_tracking_en = 1 +ad9371-phy.out_voltage1_hardwaregain = 0.000000 dB +ad9371-phy.out_voltage1_lo_leakage_tracking_en = 0 +ad9371-phy.out_voltage1_quadrature_tracking_en = 1 +ad9371-phy.in_voltage_rf_port_select_available = OFF INTERNALCALS OBS_SNIFFER SN_A SN_B SN_C ORX1_TX_LO ORX2_TX_LO ORX1_SN_LO ORX2_SN_LO +ad9371-phy.out_altvoltage1_TX_LO_frequency = 2560000000 +ad9371-phy.out_altvoltage2_RX_SN_LO_frequency = 2680000000 +ad9371-phy.in_voltage_rf_port_select_available = OFF INTERNALCALS OBS_SNIFFER SN_A SN_B SN_C ORX1_TX_LO ORX2_TX_LO ORX1_SN_LO ORX2_SN_LO +ad9371-phy.in_voltage_rf_port_select_available = OFF INTERNALCALS OBS_SNIFFER SN_A SN_B SN_C ORX1_TX_LO ORX2_TX_LO ORX1_SN_LO ORX2_SN_LO +ad9371-phy.in_voltage_rf_port_select_available = OFF INTERNALCALS OBS_SNIFFER SN_A SN_B SN_C ORX1_TX_LO ORX2_TX_LO ORX1_SN_LO ORX2_SN_LO +ad9371-phy.in_voltage0_gain_control_mode = manual +ad9371-phy.in_voltage0_quadrature_tracking_en = 1 +ad9371-phy.in_voltage0_hardwaregain = 15.000000 dB +ad9371-phy.in_voltage0_temp_comp_gain = 0.00 dB +ad9371-phy.in_voltage_rf_port_select_available = OFF INTERNALCALS OBS_SNIFFER SN_A SN_B SN_C ORX1_TX_LO ORX2_TX_LO ORX1_SN_LO ORX2_SN_LO +ad9371-phy.in_voltage1_quadrature_tracking_en = 1 +ad9371-phy.in_voltage1_hardwaregain = 15.000000 dB +ad9371-phy.in_voltage1_temp_comp_gain = 0.00 dB +ad9371-phy.in_voltage1_gain_control_mode = manual +ad9371-phy.in_voltage_rf_port_select_available = OFF INTERNALCALS OBS_SNIFFER SN_A SN_B SN_C ORX1_TX_LO ORX2_TX_LO ORX1_SN_LO ORX2_SN_LO +ad9371-phy.out_altvoltage0_RX_LO_frequency = 2680000000 +ad9371-phy.calibrate_rx_qec_en = 0 +ad9371-phy.calibrate_tx_lol_en = 0 +ad9371-phy.calibrate_vswr_en = 0 +ad9371-phy.calibrate_tx_qec_en = 0 +ad9371-phy.calibrate_clgc_en = 0 +ad9371-phy.ensm_mode = radio_on +ad9371-phy.calibrate_tx_lol_ext_en = 0 +ad9371-phy.calibrate_dpd_en = 0 +axi-ad9371-tx-hpc.out_altvoltage0_TX1_I_F1_phase = 90000 +axi-ad9371-tx-hpc.out_altvoltage0_TX1_I_F1_scale = 0.501160 +axi-ad9371-tx-hpc.out_altvoltage0_TX1_I_F1_frequency = 1999718 +axi-ad9371-tx-hpc.out_altvoltage0_TX1_I_F1_raw = 1 +axi-ad9371-tx-hpc.out_altvoltage5_TX2_I_F2_phase = 90000 +axi-ad9371-tx-hpc.out_altvoltage5_TX2_I_F2_scale = 0.000000 +axi-ad9371-tx-hpc.out_altvoltage5_TX2_I_F2_raw = 1 +axi-ad9371-tx-hpc.out_altvoltage5_TX2_I_F2_frequency = 1000327 +axi-ad9371-tx-hpc.out_altvoltage4_TX2_I_F1_frequency = 7999809 +axi-ad9371-tx-hpc.out_altvoltage4_TX2_I_F1_phase = 90000 +axi-ad9371-tx-hpc.out_altvoltage4_TX2_I_F1_scale = 0.251160 +axi-ad9371-tx-hpc.out_altvoltage4_TX2_I_F1_raw = 1 +axi-ad9371-tx-hpc.out_altvoltage6_TX2_Q_F1_frequency = 7999809 +axi-ad9371-tx-hpc.out_altvoltage6_TX2_Q_F1_raw = 1 +axi-ad9371-tx-hpc.out_altvoltage6_TX2_Q_F1_phase = 0 +axi-ad9371-tx-hpc.out_altvoltage6_TX2_Q_F1_scale = 0.251160 +axi-ad9371-tx-hpc.out_altvoltage3_TX1_Q_F2_raw = 1 +axi-ad9371-tx-hpc.out_altvoltage3_TX1_Q_F2_phase = 0 +axi-ad9371-tx-hpc.out_altvoltage3_TX1_Q_F2_scale = 0.000000 +axi-ad9371-tx-hpc.out_altvoltage3_TX1_Q_F2_frequency = 19998117 +axi-ad9371-tx-hpc.out_altvoltage7_TX2_Q_F2_raw = 1 +axi-ad9371-tx-hpc.out_altvoltage7_TX2_Q_F2_phase = 0 +axi-ad9371-tx-hpc.out_altvoltage7_TX2_Q_F2_scale = 0.000000 +axi-ad9371-tx-hpc.out_altvoltage7_TX2_Q_F2_frequency = 1000327 +axi-ad9371-tx-hpc.out_altvoltage2_TX1_Q_F1_raw = 1 +axi-ad9371-tx-hpc.out_altvoltage2_TX1_Q_F1_phase = 0 +axi-ad9371-tx-hpc.out_altvoltage2_TX1_Q_F1_scale = 0.501160 +axi-ad9371-tx-hpc.out_altvoltage2_TX1_Q_F1_frequency = 1999718 +axi-ad9371-tx-hpc.out_altvoltage1_TX1_I_F2_frequency = 19998117 +axi-ad9371-tx-hpc.out_altvoltage1_TX1_I_F2_raw = 1 +axi-ad9371-tx-hpc.out_altvoltage1_TX1_I_F2_phase = 90000 +axi-ad9371-tx-hpc.out_altvoltage1_TX1_I_F2_scale = 0.000000 +load_myk_profile_file = /targets/ARCH/ADRV9371_ZC706/USERSPACE/PROFILES/profile20MHz.txt +dds_mode_tx1 = 1 +dds_mode_tx2 = 1 +dac_buf_filename = /usr/local/lib/osc/waveforms/LTE20.mat +tx_channel_0 = 1 +tx_channel_1 = 1 +tx_channel_2 = 0 +tx_channel_3 = 0 +global_settings_show = 1 +tx_show = 1 +rx_show = 1 +obs_show = 1 +fpga_show = 1 + +[ADRV9371_ZC706] +# NO_DEBUG=0; DEBUG=1 +debug_mode = 0 +# 20MHz 40MHz 80MHz=1; 10MHz=2; 5MHz=4 +interpolation_decimation_factor = 1 +# is taken into account only if "ad9371-phy.in_voltage0_gain_control_mode = manual" +rx_gain_offset = 30 diff --git a/targets/ARCH/ADRV9371_ZC706/USERSPACE/PROFILES/ue.band7.tm1.PRB25.adrv9371-zc706.ini b/targets/ARCH/ADRV9371_ZC706/USERSPACE/PROFILES/ue.band7.tm1.PRB25.adrv9371-zc706.ini new file mode 100644 index 0000000000000000000000000000000000000000..bcdbf7716a800c39d02f49961ab1a3c537361d5b --- /dev/null +++ b/targets/ARCH/ADRV9371_ZC706/USERSPACE/PROFILES/ue.band7.tm1.PRB25.adrv9371-zc706.ini @@ -0,0 +1,85 @@ +[AD9371] +ad9371-phy.in_voltage2_rf_port_select = OFF +ad9371-phy.in_voltage2_hardwaregain = -156.000000 dB +ad9371-phy.in_voltage2_temp_comp_gain = 0.00 dB +ad9371-phy.in_voltage_rf_port_select_available = OFF INTERNALCALS OBS_SNIFFER SN_A SN_B SN_C ORX1_TX_LO ORX2_TX_LO ORX1_SN_LO ORX2_SN_LO +ad9371-phy.out_voltage0_lo_leakage_tracking_en = 0 +ad9371-phy.out_voltage0_hardwaregain = -10.000000 dB +ad9371-phy.out_voltage0_quadrature_tracking_en = 1 +ad9371-phy.out_voltage1_hardwaregain = -10.000000 dB +ad9371-phy.out_voltage1_lo_leakage_tracking_en = 0 +ad9371-phy.out_voltage1_quadrature_tracking_en = 1 +ad9371-phy.in_voltage_rf_port_select_available = OFF INTERNALCALS OBS_SNIFFER SN_A SN_B SN_C ORX1_TX_LO ORX2_TX_LO ORX1_SN_LO ORX2_SN_LO +ad9371-phy.out_altvoltage1_TX_LO_frequency = 2535000000 +ad9371-phy.out_altvoltage2_RX_SN_LO_frequency = 2655000000 +ad9371-phy.in_voltage_rf_port_select_available = OFF INTERNALCALS OBS_SNIFFER SN_A SN_B SN_C ORX1_TX_LO ORX2_TX_LO ORX1_SN_LO ORX2_SN_LO +ad9371-phy.in_voltage_rf_port_select_available = OFF INTERNALCALS OBS_SNIFFER SN_A SN_B SN_C ORX1_TX_LO ORX2_TX_LO ORX1_SN_LO ORX2_SN_LO +ad9371-phy.in_voltage_rf_port_select_available = OFF INTERNALCALS OBS_SNIFFER SN_A SN_B SN_C ORX1_TX_LO ORX2_TX_LO ORX1_SN_LO ORX2_SN_LO +ad9371-phy.in_voltage0_gain_control_mode = automatic +ad9371-phy.in_voltage0_quadrature_tracking_en = 1 +ad9371-phy.in_voltage0_hardwaregain = 30.000000 dB +ad9371-phy.in_voltage0_temp_comp_gain = 0.00 dB +ad9371-phy.in_voltage_rf_port_select_available = OFF INTERNALCALS OBS_SNIFFER SN_A SN_B SN_C ORX1_TX_LO ORX2_TX_LO ORX1_SN_LO ORX2_SN_LO +ad9371-phy.in_voltage1_quadrature_tracking_en = 1 +ad9371-phy.in_voltage1_hardwaregain = 30.000000 dB +ad9371-phy.in_voltage1_temp_comp_gain = 0.00 dB +ad9371-phy.in_voltage1_gain_control_mode = automatic +ad9371-phy.in_voltage_rf_port_select_available = OFF INTERNALCALS OBS_SNIFFER SN_A SN_B SN_C ORX1_TX_LO ORX2_TX_LO ORX1_SN_LO ORX2_SN_LO +ad9371-phy.out_altvoltage0_RX_LO_frequency = 2655000000 +ad9371-phy.calibrate_rx_qec_en = 0 +ad9371-phy.calibrate_tx_lol_en = 0 +ad9371-phy.calibrate_vswr_en = 0 +ad9371-phy.calibrate_tx_qec_en = 0 +ad9371-phy.calibrate_clgc_en = 0 +ad9371-phy.ensm_mode = radio_on +ad9371-phy.calibrate_tx_lol_ext_en = 0 +ad9371-phy.calibrate_dpd_en = 0 +axi-ad9371-tx-hpc.out_altvoltage0_TX1_I_F1_phase = 90000 +axi-ad9371-tx-hpc.out_altvoltage0_TX1_I_F1_scale = 0.501160 +axi-ad9371-tx-hpc.out_altvoltage0_TX1_I_F1_frequency = 1999718 +axi-ad9371-tx-hpc.out_altvoltage0_TX1_I_F1_raw = 1 +axi-ad9371-tx-hpc.out_altvoltage5_TX2_I_F2_phase = 90000 +axi-ad9371-tx-hpc.out_altvoltage5_TX2_I_F2_scale = 0.000000 +axi-ad9371-tx-hpc.out_altvoltage5_TX2_I_F2_raw = 1 +axi-ad9371-tx-hpc.out_altvoltage5_TX2_I_F2_frequency = 1000327 +axi-ad9371-tx-hpc.out_altvoltage4_TX2_I_F1_frequency = 7999809 +axi-ad9371-tx-hpc.out_altvoltage4_TX2_I_F1_phase = 90000 +axi-ad9371-tx-hpc.out_altvoltage4_TX2_I_F1_scale = 0.251160 +axi-ad9371-tx-hpc.out_altvoltage4_TX2_I_F1_raw = 1 +axi-ad9371-tx-hpc.out_altvoltage6_TX2_Q_F1_frequency = 7999809 +axi-ad9371-tx-hpc.out_altvoltage6_TX2_Q_F1_raw = 1 +axi-ad9371-tx-hpc.out_altvoltage6_TX2_Q_F1_phase = 0 +axi-ad9371-tx-hpc.out_altvoltage6_TX2_Q_F1_scale = 0.251160 +axi-ad9371-tx-hpc.out_altvoltage3_TX1_Q_F2_raw = 1 +axi-ad9371-tx-hpc.out_altvoltage3_TX1_Q_F2_phase = 0 +axi-ad9371-tx-hpc.out_altvoltage3_TX1_Q_F2_scale = 0.000000 +axi-ad9371-tx-hpc.out_altvoltage3_TX1_Q_F2_frequency = 19998117 +axi-ad9371-tx-hpc.out_altvoltage7_TX2_Q_F2_raw = 1 +axi-ad9371-tx-hpc.out_altvoltage7_TX2_Q_F2_phase = 0 +axi-ad9371-tx-hpc.out_altvoltage7_TX2_Q_F2_scale = 0.000000 +axi-ad9371-tx-hpc.out_altvoltage7_TX2_Q_F2_frequency = 1000327 +axi-ad9371-tx-hpc.out_altvoltage2_TX1_Q_F1_raw = 1 +axi-ad9371-tx-hpc.out_altvoltage2_TX1_Q_F1_phase = 0 +axi-ad9371-tx-hpc.out_altvoltage2_TX1_Q_F1_scale = 0.501160 +axi-ad9371-tx-hpc.out_altvoltage2_TX1_Q_F1_frequency = 1999718 +axi-ad9371-tx-hpc.out_altvoltage1_TX1_I_F2_frequency = 19998117 +axi-ad9371-tx-hpc.out_altvoltage1_TX1_I_F2_raw = 1 +axi-ad9371-tx-hpc.out_altvoltage1_TX1_I_F2_phase = 90000 +axi-ad9371-tx-hpc.out_altvoltage1_TX1_I_F2_scale = 0.000000 +load_myk_profile_file = /targets/ARCH/ADRV9371_ZC706/USERSPACE/PROFILES/profile_rx30_Tx60_syr.txt +dds_mode_tx1 = 1 +dds_mode_tx2 = 1 +dac_buf_filename = /usr/local/lib/osc/waveforms/LTE20.mat +tx_channel_0 = 1 +tx_channel_1 = 1 +tx_channel_2 = 0 +tx_channel_3 = 0 +global_settings_show = 1 +tx_show = 1 +rx_show = 1 +obs_show = 1 +fpga_show = 1 + +[ADRV9371_ZC706] +debug_mode = 0 +interpolation_decimation_factor = 4 diff --git a/targets/ARCH/ADRV9371_ZC706/USERSPACE/PROFILES/ue.band7.tm1.PRB50.adrv9371-zc706.ini b/targets/ARCH/ADRV9371_ZC706/USERSPACE/PROFILES/ue.band7.tm1.PRB50.adrv9371-zc706.ini new file mode 100644 index 0000000000000000000000000000000000000000..a23a765503599ff5486ffa1ad1d380127852b5e7 --- /dev/null +++ b/targets/ARCH/ADRV9371_ZC706/USERSPACE/PROFILES/ue.band7.tm1.PRB50.adrv9371-zc706.ini @@ -0,0 +1,85 @@ +[AD9371] +ad9371-phy.in_voltage2_rf_port_select = OFF +ad9371-phy.in_voltage2_hardwaregain = -156.000000 dB +ad9371-phy.in_voltage2_temp_comp_gain = 0.00 dB +ad9371-phy.in_voltage_rf_port_select_available = OFF INTERNALCALS OBS_SNIFFER SN_A SN_B SN_C ORX1_TX_LO ORX2_TX_LO ORX1_SN_LO ORX2_SN_LO +ad9371-phy.out_voltage0_lo_leakage_tracking_en = 0 +ad9371-phy.out_voltage0_hardwaregain = -10.000000 dB +ad9371-phy.out_voltage0_quadrature_tracking_en = 1 +ad9371-phy.out_voltage1_hardwaregain = -10.000000 dB +ad9371-phy.out_voltage1_lo_leakage_tracking_en = 0 +ad9371-phy.out_voltage1_quadrature_tracking_en = 1 +ad9371-phy.in_voltage_rf_port_select_available = OFF INTERNALCALS OBS_SNIFFER SN_A SN_B SN_C ORX1_TX_LO ORX2_TX_LO ORX1_SN_LO ORX2_SN_LO +ad9371-phy.out_altvoltage1_TX_LO_frequency = 2535000000 +ad9371-phy.out_altvoltage2_RX_SN_LO_frequency = 2655000000 +ad9371-phy.in_voltage_rf_port_select_available = OFF INTERNALCALS OBS_SNIFFER SN_A SN_B SN_C ORX1_TX_LO ORX2_TX_LO ORX1_SN_LO ORX2_SN_LO +ad9371-phy.in_voltage_rf_port_select_available = OFF INTERNALCALS OBS_SNIFFER SN_A SN_B SN_C ORX1_TX_LO ORX2_TX_LO ORX1_SN_LO ORX2_SN_LO +ad9371-phy.in_voltage_rf_port_select_available = OFF INTERNALCALS OBS_SNIFFER SN_A SN_B SN_C ORX1_TX_LO ORX2_TX_LO ORX1_SN_LO ORX2_SN_LO +ad9371-phy.in_voltage0_gain_control_mode = automatic +ad9371-phy.in_voltage0_quadrature_tracking_en = 1 +ad9371-phy.in_voltage0_hardwaregain = 30.000000 dB +ad9371-phy.in_voltage0_temp_comp_gain = 0.00 dB +ad9371-phy.in_voltage_rf_port_select_available = OFF INTERNALCALS OBS_SNIFFER SN_A SN_B SN_C ORX1_TX_LO ORX2_TX_LO ORX1_SN_LO ORX2_SN_LO +ad9371-phy.in_voltage1_quadrature_tracking_en = 1 +ad9371-phy.in_voltage1_hardwaregain = 30.000000 dB +ad9371-phy.in_voltage1_temp_comp_gain = 0.00 dB +ad9371-phy.in_voltage1_gain_control_mode = automatic +ad9371-phy.in_voltage_rf_port_select_available = OFF INTERNALCALS OBS_SNIFFER SN_A SN_B SN_C ORX1_TX_LO ORX2_TX_LO ORX1_SN_LO ORX2_SN_LO +ad9371-phy.out_altvoltage0_RX_LO_frequency = 2655000000 +ad9371-phy.calibrate_rx_qec_en = 0 +ad9371-phy.calibrate_tx_lol_en = 0 +ad9371-phy.calibrate_vswr_en = 0 +ad9371-phy.calibrate_tx_qec_en = 0 +ad9371-phy.calibrate_clgc_en = 0 +ad9371-phy.ensm_mode = radio_on +ad9371-phy.calibrate_tx_lol_ext_en = 0 +ad9371-phy.calibrate_dpd_en = 0 +axi-ad9371-tx-hpc.out_altvoltage0_TX1_I_F1_phase = 90000 +axi-ad9371-tx-hpc.out_altvoltage0_TX1_I_F1_scale = 0.501160 +axi-ad9371-tx-hpc.out_altvoltage0_TX1_I_F1_frequency = 1999718 +axi-ad9371-tx-hpc.out_altvoltage0_TX1_I_F1_raw = 1 +axi-ad9371-tx-hpc.out_altvoltage5_TX2_I_F2_phase = 90000 +axi-ad9371-tx-hpc.out_altvoltage5_TX2_I_F2_scale = 0.000000 +axi-ad9371-tx-hpc.out_altvoltage5_TX2_I_F2_raw = 1 +axi-ad9371-tx-hpc.out_altvoltage5_TX2_I_F2_frequency = 1000327 +axi-ad9371-tx-hpc.out_altvoltage4_TX2_I_F1_frequency = 7999809 +axi-ad9371-tx-hpc.out_altvoltage4_TX2_I_F1_phase = 90000 +axi-ad9371-tx-hpc.out_altvoltage4_TX2_I_F1_scale = 0.251160 +axi-ad9371-tx-hpc.out_altvoltage4_TX2_I_F1_raw = 1 +axi-ad9371-tx-hpc.out_altvoltage6_TX2_Q_F1_frequency = 7999809 +axi-ad9371-tx-hpc.out_altvoltage6_TX2_Q_F1_raw = 1 +axi-ad9371-tx-hpc.out_altvoltage6_TX2_Q_F1_phase = 0 +axi-ad9371-tx-hpc.out_altvoltage6_TX2_Q_F1_scale = 0.251160 +axi-ad9371-tx-hpc.out_altvoltage3_TX1_Q_F2_raw = 1 +axi-ad9371-tx-hpc.out_altvoltage3_TX1_Q_F2_phase = 0 +axi-ad9371-tx-hpc.out_altvoltage3_TX1_Q_F2_scale = 0.000000 +axi-ad9371-tx-hpc.out_altvoltage3_TX1_Q_F2_frequency = 19998117 +axi-ad9371-tx-hpc.out_altvoltage7_TX2_Q_F2_raw = 1 +axi-ad9371-tx-hpc.out_altvoltage7_TX2_Q_F2_phase = 0 +axi-ad9371-tx-hpc.out_altvoltage7_TX2_Q_F2_scale = 0.000000 +axi-ad9371-tx-hpc.out_altvoltage7_TX2_Q_F2_frequency = 1000327 +axi-ad9371-tx-hpc.out_altvoltage2_TX1_Q_F1_raw = 1 +axi-ad9371-tx-hpc.out_altvoltage2_TX1_Q_F1_phase = 0 +axi-ad9371-tx-hpc.out_altvoltage2_TX1_Q_F1_scale = 0.501160 +axi-ad9371-tx-hpc.out_altvoltage2_TX1_Q_F1_frequency = 1999718 +axi-ad9371-tx-hpc.out_altvoltage1_TX1_I_F2_frequency = 19998117 +axi-ad9371-tx-hpc.out_altvoltage1_TX1_I_F2_raw = 1 +axi-ad9371-tx-hpc.out_altvoltage1_TX1_I_F2_phase = 90000 +axi-ad9371-tx-hpc.out_altvoltage1_TX1_I_F2_scale = 0.000000 +load_myk_profile_file = /targets/ARCH/ADRV9371_ZC706/USERSPACE/PROFILES/profile_rx30_Tx60_syr.txt +dds_mode_tx1 = 1 +dds_mode_tx2 = 1 +dac_buf_filename = /usr/local/lib/osc/waveforms/LTE20.mat +tx_channel_0 = 1 +tx_channel_1 = 1 +tx_channel_2 = 0 +tx_channel_3 = 0 +global_settings_show = 1 +tx_show = 1 +rx_show = 1 +obs_show = 1 +fpga_show = 1 + +[ADRV9371_ZC706] +debug_mode = 0 +interpolation_decimation_factor = 2 diff --git a/targets/ARCH/ADRV9371_ZC706/readme.txt b/targets/ARCH/ADRV9371_ZC706/readme.txt new file mode 100644 index 0000000000000000000000000000000000000000..05b3bc1b7d90ee2f922b101b96e14f3a321a5942 --- /dev/null +++ b/targets/ARCH/ADRV9371_ZC706/readme.txt @@ -0,0 +1,17 @@ +Common command line: +-------------------- +cd /openairinterface5g/ +source oaienv + +HWLAT application: +------------------ +./cmake_targets/build_oai -c -C -w ADRV9371_ZC706 --HWLAT +./cmake_targets/lte-hwlat/build/lte-hwlat + +LTE-SOFTMODEM application: +-------------------------- +./cmake_targets/build_oai -c --eNB --UE --noS1 -w ADRV9371_ZC706 +sudo su +source oaienv +source ./targets/bin/init_nas_nos1 UE +./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C 2680000000 -r100 --ue-scan-carrier --ue-txgain 0 --ue-rxgain 5 -S -A 6 --ue-max-power -25 --phy-test -g 7 --rf-config-file ./targets/ARCH/ADRV9371_ZC706/USERSPACE/PROFILES/ue.band7.tm1.PRB100.adrv9371-zc706_HWgain15dB.ini diff --git a/targets/ARCH/ADRV9371_ZC706/slib/libadrv9371_zc706.so b/targets/ARCH/ADRV9371_ZC706/slib/libadrv9371_zc706.so new file mode 100755 index 0000000000000000000000000000000000000000..c060bfdc57da7c5213e7b6f4c6b576f28a9cff08 Binary files /dev/null and b/targets/ARCH/ADRV9371_ZC706/slib/libadrv9371_zc706.so differ diff --git a/targets/ARCH/COMMON/common_lib.c b/targets/ARCH/COMMON/common_lib.c index d74b1c6d4fed2d65640c1d5989e2ec846c642dcf..c0a3e8a7203abecf1aeff6a9a47153304173a465 100644 --- a/targets/ARCH/COMMON/common_lib.c +++ b/targets/ARCH/COMMON/common_lib.c @@ -60,6 +60,12 @@ case USRP_X300_DEV: case NONE_DEV: printf("[%s] has not loaded a HW device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); break; + case ADRV9371_ZC706_DEV: + printf("[%s] has loaded ADRV9371_ZC706 device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); + break; + case UEDv2_DEV: + printf("[%s] has loaded UEDv2 device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); + break; default: printf("[%s] invalid HW device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); return -1; diff --git a/targets/ARCH/COMMON/common_lib.h b/targets/ARCH/COMMON/common_lib.h index 433e29e97db7b15322b51d8f3282daa91b922c09..7460c4849bfa383048a100ef4184b562d5856f0e 100644 --- a/targets/ARCH/COMMON/common_lib.h +++ b/targets/ARCH/COMMON/common_lib.h @@ -97,6 +97,10 @@ typedef enum { LMSSDR_DEV, /*!\brief device is NONE*/ NONE_DEV, + /*!\brief device is ADRV9371_ZC706 */ + ADRV9371_ZC706_DEV, + /*!\brief device is UEDv2 */ + UEDv2_DEV, MAX_RF_DEV_TYPE } dev_type_t; @@ -216,6 +220,14 @@ typedef struct { unsigned int sf_write_delay; // write delay in replay mode unsigned int eth_mtu; // ethernet MTU #endif + + //! number of samples per tti + unsigned int samples_per_tti; + //! the sample rate for receive. + double rx_sample_rate; + //! the sample rate for transmit. + double tx_sample_rate; + } openair0_config_t; /*! \brief RF mapping */ diff --git a/targets/COMMON/openairinterface5g_limits.h b/targets/COMMON/openairinterface5g_limits.h index 98de4a024f5225e7d061dc3d1ba09c2ec8802bad..4ce85f4cad6dd6b56f99042bc18619cadf86aec2 100644 --- a/targets/COMMON/openairinterface5g_limits.h +++ b/targets/COMMON/openairinterface5g_limits.h @@ -1,7 +1,7 @@ #ifndef OPENAIRINTERFACE5G_LIMITS_H_ #define OPENAIRINTERFACE5G_LIMITS_H_ -#if defined(CBMIMO1) || defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_LMSSDR) +#if defined(CBMIMO1) || defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706) # define NUMBER_OF_eNB_MAX 1 # define NUMBER_OF_RU_MAX 2 # define NUMBER_OF_UE_MAX 16 diff --git a/targets/RT/USER/lte-hwlat.c b/targets/RT/USER/lte-hwlat.c new file mode 100755 index 0000000000000000000000000000000000000000..9f5a3306aa20128cd856e7c416cc2318688d7a62 --- /dev/null +++ b/targets/RT/USER/lte-hwlat.c @@ -0,0 +1,944 @@ +/* + * 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 + */ + +#define _GNU_SOURCE +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <sys/ioctl.h> +#include <sys/types.h> +#include <sys/mman.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <sched.h> +#include <linux/sched.h> +#include <signal.h> +#include <execinfo.h> +#include <getopt.h> +#include <syscall.h> +#include <sys/sysinfo.h> + +#include "assertions.h" +#include "PHY/types.h" + +#include "PHY/defs.h" + +#include <sys/time.h> +#define GET_TIME_INIT(num) struct timeval _timers[num] +#define GET_TIME_VAL(num) gettimeofday(&_timers[num], NULL) +#define TIME_VAL_TO_MS(num) (((double)_timers[num].tv_sec*1000.0) + ((double)_timers[num].tv_usec/1000.0)) + +#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all +//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all + +#include "../../ARCH/COMMON/common_lib.h" + +#include "PHY/extern.h" +#include "SCHED/extern.h" +#include "LAYER2/MAC/extern.h" +#include "LAYER2/MAC/proto.h" + +#define RIFFA_CHANNEL_TESTER 0 +#define RIFFA_CHANNEL_TESTER2 0 +#define RIFFA_CHANNEL_DATA1 1 + +volatile int oai_exit = 0; + +openair0_config_t openair0_cfg[MAX_CARDS]; + +#if 0 +#define NB_ANTENNAS_RX 4 + +#define DevAssert(cOND) _Assert_(cOND, _Assert_Exit_, "") +#define malloc16(x) memalign(16,x) + +#ifdef 0 +static inline void* malloc16_clear( size_t size ) +{ +#ifdef __AVX2__ + void* ptr = memalign(32, size); +#else + void* ptr = memalign(16, size); +#endif + if(ptr) + memset( ptr, 0, size ); + return ptr; +} +#endif + +#endif + +typedef struct latency_stat { + uint64_t counter; + + uint64_t stat250; + uint64_t stat500; + uint64_t stat600; + uint64_t stat700; + uint64_t stat800; + + uint64_t stat1300; + uint64_t stat1500; + uint64_t stat2000; + uint64_t stat2500; + uint64_t stat3000; + + uint64_t stat880; + uint64_t stat960; + uint64_t stat1040; + uint64_t stat1120; + uint64_t stat1200; +} latency_stat_t; + + +typedef struct timing_stats { + char *name; + double min; + double max; + double total; + unsigned int count; +} timing_stats_t; + + +//static struct timespec get_timespec_diff( +// struct timespec *start, +// struct timespec *stop ) +//{ +// struct timespec result; +// +// if ( ( stop->tv_nsec - start->tv_nsec ) < 0 ) { +// result.tv_sec = stop->tv_sec - start->tv_sec - 1; +// result.tv_nsec = stop->tv_nsec - start->tv_nsec + 1000000000; +// } +// else { +// result.tv_sec = stop->tv_sec - start->tv_sec; +// result.tv_nsec = stop->tv_nsec - start->tv_nsec; +// } +// +// return result; +//} + + +//static void measure_time ( +// openair0_device *rf_device, +// struct timespec *start, +// struct timespec *stop, +// timing_stats_t *stats, +// boolean_t START, +// uint8_t PRINT_INTERVAL ) +//{ +// if ( START ) { +// clock_gettime( CLOCK_MONOTONIC, start ); +// } +// else { +// clock_gettime( CLOCK_MONOTONIC, stop ); +// +// struct timespec diff; +// double current = 0; +//// boolean_t show_stats = false; +// +// diff = get_timespec_diff( start, stop ); +// current = (double)diff.tv_sec * 1000000 + (double)diff.tv_nsec / 1000; +// +// if ( current > stats->max ) { +// stats->max = current; +//// show_stats = true; +// } +// if ( stats->min == 0 || current < stats->min ) { +// stats->min = current; +//// show_stats = true; +// } +// stats->total += current; +// +//// if ( show_stats ) { +//// rf_device.trx_get_stats_func( &rf_device ); +//// } +// +//// if ( stats->count % PRINT_INTERVAL == 0 ) { +//// double avg = stats->total / ( stats->count + 1 ); +//// printf( "[%s][%d] Current : %.2lf µs, Min : %.2lf µs, Max : %.2lf µs, Avg : %.2lf µs\n", +//// stats->count, stats->name, current, stats->min, stats->max, avg ); +//// } +// +// stats->count++; +// } +//} +int32_t **rxdata; +int32_t **txdata; + +int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg); + +static inline void saif_meas(int frame_rx, int subframe_rx) { + static latency_stat_t __thread latency_stat; + static struct timespec __thread last= {0}; + struct timespec now; + clock_gettime(CLOCK_MONOTONIC_RAW, &now); + if ( last.tv_sec ) { + uint64_t diffTime = ((uint64_t)now.tv_sec *1000 *1000 *1000 + now.tv_nsec) - + ((uint64_t)last.tv_sec *1000 *1000 *1000 + last.tv_nsec); + diffTime/=1000; + latency_stat.counter++; + + if ( diffTime <= 800 ) { + if (diffTime < 250 ) + latency_stat.stat250++; + else if (diffTime < 500 ) + latency_stat.stat500++; + else if (diffTime < 600 ) + latency_stat.stat600++; + else if (diffTime < 700 ) + latency_stat.stat700++; + else + latency_stat.stat800++; + } + else if ( diffTime > 1200 ) { + if (diffTime < 1500 ) + latency_stat.stat1300++; + else if ( diffTime < 2000 ) + latency_stat.stat1500++; + else if ( diffTime < 2500 ) + latency_stat.stat2000++; + else if ( diffTime < 3000 ) + latency_stat.stat2500++; + else + latency_stat.stat3000++; + } + else + if (diffTime <= 880 ) + latency_stat.stat880++; + else if (diffTime <= 960 ) + latency_stat.stat960++; + else if (diffTime <= 1040 ) + latency_stat.stat1040++; + else if (diffTime < 1120 ) + latency_stat.stat1120++; + else + latency_stat.stat1200++; + + + if ( (diffTime>=1500) || ( !(frame_rx%1024) && subframe_rx == 0 ) ) { + time_t current=time(NULL); + printf("\n"); + printf("%.2f Period stats cnt=%7.7ld 0.. 250=%7.7ld 250.. 500=%7.7ld 500.. 600=%7.7ld 600.. 700=%7.7ld 700.. 800=%7.7ld - (frame_rx=%d) - %s", + now.tv_sec+(double)now.tv_nsec/1e9, + latency_stat.counter, + latency_stat.stat250, latency_stat.stat500, + latency_stat.stat600, latency_stat.stat700, + latency_stat.stat800, + frame_rx, + ctime(¤t)); + printf("%.2f Period stats cnt=%7.7ld 800.. 880=%7.7ld 880.. 960=%7.7ld 960..1040=%7.7ld 1040..1120=%7.7ld 1120..1200=%7.7ld - (frame_rx=%d) - %s", + now.tv_sec+(double)now.tv_nsec/1e9, + latency_stat.counter, + latency_stat.stat880, latency_stat.stat960, + latency_stat.stat1040, latency_stat.stat1120, + latency_stat.stat1200, + frame_rx, + ctime(¤t)); + printf("%.2f Period stats cnt=%7.7ld 1200..1300=%7.7ld 1300..1500=%7.7ld 1500..2000=%7.7ld 2000..2500=%7.7ld >3000=%7.7ld - (frame_rx=%d) - %s", + now.tv_sec+(double)now.tv_nsec/1e9, + latency_stat.counter, + latency_stat.stat1300, latency_stat.stat1500, + latency_stat.stat2000, latency_stat.stat2500, + latency_stat.stat3000, + frame_rx, + ctime(¤t)); + fflush(stdout); + } + } + last=now; +} +/* End of Changed by SYRTEM */ + +void exit_fun(const char* s) +{ + + if (s != NULL) { + printf("%s %s() Exiting OAI softmodem: %s\n",__FILE__, __FUNCTION__, s); + } + + oai_exit = 1; + +} + + +void init_thread(int sched_runtime, int sched_deadline, int sched_fifo, char * name) { + +#ifdef DEADLINE_SCHEDULER + if (sched_runtime!=0) { + struct sched_attr attr= {0}; + attr.size = sizeof(attr); + // This creates a .5 ms fpga_recv_cnt reservation + attr.sched_policy = SCHED_DEADLINE; + attr.sched_runtime = sched_runtime; + attr.sched_deadline = sched_deadline; + attr.sched_period = 0; + AssertFatal(sched_setattr(0, &attr, 0) == 0, + "[SCHED] main eNB thread: sched_setattr failed %s \n",perror(errno)); + LOG_I(HW,"[SCHED][eNB] eNB main deadline thread %lu started on CPU %d\n", + (unsigned long)gettid(), sched_getcpu()); + } + +#else +#ifdef CPU_AFFINITY + if (get_nprocs() >2) { + for (j = 1; j < get_nprocs(); j++) + CPU_SET(j, &cpuset); + } + AssertFatal( 0 == pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset)==0,""); +#endif + struct sched_param sp; + sp.sched_priority = sched_fifo; + AssertFatal(pthread_setschedparam(pthread_self(),SCHED_FIFO,&sp)==0, + "Can't set thread priority, Are you root?\n"); +#endif + + // Lock memory from swapping. This is a process wide call (not constraint to this thread). + mlockall(MCL_CURRENT | MCL_FUTURE); + pthread_setname_np( pthread_self(), name ); + +} + + +int main(void) +{ + int ret; + uint64_t i; + openair0_device rf_device; + openair0_timestamp timestamp = 0; + + int sub_frame = 0; + unsigned int frame_rx = 0; + + unsigned int nb_antennas_tx = 1; + unsigned int nb_antennas_rx = 1; + + + openair0_cfg[0].mmapped_dma = 0; + openair0_cfg[0].configFilename = NULL; + openair0_cfg[0].duplex_mode = duplex_mode_FDD; + + uint32_t **sendbuff = NULL; + uint32_t **recvbuff = NULL; + uint32_t expected_value = 0; + uint32_t received_value = 0; + int nsamp = 0; // 1 ms + int antenna_id = 1; + int c = 0; + int numIter = 0; + int fpga_loop = 0; +#if RIFFA_CHANNEL_DATA1 + uint64_t first_ts = 0; + uint8_t is_first_ts = 0; + uint64_t trx_read_cnt = 0; + uint32_t j = 0; + uint32_t err_cnt = 0; +#else + int failure = 0; +#endif +#if 0 // 5MHz BW + unsigned int nb_sample_per_tti = 7680; + openair0_cfg[0].sample_rate = 7.68e6; + openair0_cfg[0].samples_per_frame = nb_sample_per_tti*10; + openair0_cfg[0].rx_bw = 2.5e6; + openair0_cfg[0].tx_bw = 2.5e6; + openair0_cfg[0].num_rb_dl = 25; +#endif + +#if 0 // 10MHz BW + unsigned int nb_sample_per_tti = 15360; + openair0_cfg[0].sample_rate = 15.36e6; + openair0_cfg[0].samples_per_frame = nb_sample_per_tti*10; + openair0_cfg[0].rx_bw = 5.0e6; + openair0_cfg[0].tx_bw = 5.0e6; + openair0_cfg[0].num_rb_dl = 50; +#endif + +#if 1 // 20MHz BW + unsigned int nb_sample_per_tti = 30720; + openair0_cfg[0].sample_rate = 30.72e6; + openair0_cfg[0].samples_per_frame = nb_sample_per_tti*10; + openair0_cfg[0].rx_bw = 10.0e6; + openair0_cfg[0].tx_bw = 10.0e6; + openair0_cfg[0].num_rb_dl = 100; +#endif + + const char *openair_dir = getenv("OPENAIR_DIR"); + const char *ini_file = "/targets/ARCH/ADRV9371_ZC706/USERSPACE/PROFILES/ue.band7.tm1.PRB100.adrv9371-zc706_HWgain15dB.ini"; + + int readBlockSize; + void* rxp[nb_antennas_rx]; + void* txp[nb_antennas_tx]; + +// int32_t rxdata[1][nb_sample_per_tti*10+2048]; +#if 0 + int32_t **rxdata; +#endif +// init_thread(100000, 500000, sched_get_priority_max(SCHED_FIFO),"main UE"); + + printf("LTE HARDWARE Latency debug utility \n"); + printf("INIT data buffers \n"); + +#if 0 + rxdata = (int32_t**)memalign(32, nb_antennas_rx*sizeof(int32_t*) ); + rxdata[0] = (int32_t*)memalign(32,(nb_sample_per_tti*10+2048)*sizeof(int32_t)); +#else + rxdata = (int32_t**)malloc16( nb_antennas_rx*sizeof(int32_t*) ); + txdata = (int32_t**)malloc16( nb_antennas_tx*sizeof(int32_t*) ); + rxdata[0] = (int32_t*)malloc16_clear( 307200*sizeof(int32_t) ); + txdata[0] = (int32_t*)malloc16_clear( 307200*sizeof(int32_t) ); +#endif + + printf("INIT done\n"); + + memset(&rf_device, 0, sizeof(openair0_device)); + + rf_device.host_type = BBU_HOST; + openair0_cfg[0].duplex_mode = duplex_mode_FDD; + openair0_cfg[0].rx_num_channels = 1; + openair0_cfg[0].tx_num_channels = 1; + + // configure channel 0 + for (i=0; i<openair0_cfg[0].rx_num_channels; i++) + { + printf("configure channel %d \n",i); + openair0_cfg[0].autocal[i] = 1; + openair0_cfg[0].rx_freq[i] = 2680000000; + openair0_cfg[0].tx_freq[i] = 2560000000; + openair0_cfg[0].rx_gain[i] = 61; + openair0_cfg[0].tx_gain[i] = 90; + } + + if (openair_dir) + { + openair0_cfg[0].configFilename = malloc(strlen(openair_dir) + strlen(ini_file) + 2); + sprintf(openair0_cfg[0].configFilename, "%s/%s", openair_dir, ini_file); + } +// printf("openair0_cfg[0].configFilename:%s\n", openair0_cfg[0].configFilename); + + ret = openair0_device_load( &rf_device, &openair0_cfg[0] ); + if (ret != 0){ + exit_fun("Error loading device library"); + exit(-1); + } + +/* Runtime test + * 30 720 000 samples (4 bytes) for 1 sec (30 720 for 1 ms) + */ + puts( "* Starting the device" ); + +// TIMING +// struct timespec start, stop; // tx_start, tx_stop; +// timing_stats_t rx_stats, tx_stats; + +// rx_stats.name = strdup( "RX" ); +// tx_stats.name = strdup( "TX" ); +// TIMING + + nsamp = 307200; // 1 ms + sendbuff = memalign( 128, nb_antennas_rx * sizeof( uint32_t * ) ); + sendbuff[0] = memalign( 128, nsamp * sizeof( uint32_t ) ); + recvbuff = memalign( 128, nb_antennas_rx * sizeof( uint32_t * ) ); + recvbuff[0] = memalign( 128, nsamp * sizeof( uint32_t ) ); + +// Create dummy buffer + for ( c = 0; c < nsamp; c++ ) { +// sendbuff[0][c] = (c+1); + sendbuff[0][c] = (c+1)*16; +// sendbuff[0][c] = (nsamp-c); + recvbuff[0][c] = 0; + } + + GET_TIME_INIT(3); + + if ( rf_device.trx_start_func( &rf_device ) < 0 ) { + printf( " device could not be started !\n" ); + return -1; + } + + // read 30720 + + // write 30720 ts+2*30720 + + // if tsread >= 2-307200 -> check expected value + status (RxoVer TxUnder) + + rxp[0] = (void*)&rxdata[0][0]; + txp[0] = (void*)&txdata[0][0]; + timestamp = 0; + nsamp = 30720; // 30720 => 1ms buffer + trx_read_cnt = 100000; // 1 loop => 1ms (10sec=10000; 15min = 900000) + antenna_id = 1; + int diff = 0; + int compare_start = 0; + + uint32_t looploop=0; + uint64_t error_cnt = 0; + uint64_t error_ts_start; + + for (i = 0; i < trx_read_cnt; i++) + { + +// printf("\n\n"); + + +// ret = rf_device.trx_read_func( &rf_device, ×tamp, &(rxp[0][(i*30720)%307200]), nsamp, antenna_id ); +// ret = rf_device.trx_read_func( &rf_device, ×tamp, recvbuff[0][(i*30720)%307200], nsamp, antenna_id ); + rxp[0] = (void*)&rxdata[0][(i*30720)%307200]; + GET_TIME_VAL(0); + ret = rf_device.trx_read_func( &rf_device, ×tamp, rxp, nsamp, antenna_id ); + GET_TIME_VAL(1); + + if (ret != nsamp) + { + printf("Error: nsamp received (%d) != nsamp required (%d)\n", ret, nsamp); + fflush(stdout); + return (-1); + } + if (!is_first_ts) + { + first_ts = timestamp; + is_first_ts = 1; + } + +// printf("%d - trx_read_func ret=%d - ts = %d - @=0x%08lx\n", i, ret, timestamp, rxp[0] ); + + txp[0] = (void*)&(txdata[0][ ((i*30720)%307200+2*30720)%307200 ]); +// printf(" i=%d @txp[0][0] = 0x%016lx\n", i, &(((uint32_t *)txp[0])[0]) ); +// printf(" i=%d @txp[0][1] = 0x%016lx\n", i, &(((uint32_t *)txp[0])[1]) ); + + for ( c = 0; c < nsamp; c++ ) + { + (((uint32_t *)txp[0])[c]) = ( (((timestamp+c+2*30720)<<4)&0x0000FFF0) + (((timestamp+c+2*30720)<<8)&0xFFF00000) ); + } + +// printf(" txp[0][%d] = 0x%x\n",0,((uint32_t *)(txp[0]))[0]); +// printf(" txp[0][%d] = 0x%x\n",1,((uint32_t *)(txp[0]))[1]); +// printf(" ...\n"); +// printf(" txp[0][%d] = 0x%x\n",nsamp-2,((uint32_t *)(txp[0]))[nsamp-2]); +// printf(" txp[0][%d] = 0x%x\n",nsamp-1,((uint32_t *)(txp[0]))[nsamp-1]); + + + ret = rf_device.trx_write_func( &rf_device, (timestamp+2*30720), txp, nsamp, antenna_id, false ); + if (ret != nsamp) + { + printf("Error: nsamp sent (%d) != nsamp required (%d)\n", ret, nsamp); + fflush(stdout); + return (-1); + } + +// printf("%d - trx_write_func ret=%d - ts = %d - @=0x%08lx\n", i, ret, (timestamp+2*30720), txp[0] ); + + + if (timestamp >= (first_ts + 2 * 307200)) + { + + // check Rx Overflow + + // check Tx Underflow + + // check Expected Value + for ( c = 0; c < nsamp; c++ ) + { + +// LOOPBACK +#if 1 + expected_value = ((timestamp + c)&0xFFFFFF); + received_value = ((uint32_t *)(rxp[0]))[c]; + received_value = ((received_value)&0xFFF) + ((received_value>>4)&0xFFF000); + + if (compare_start == 0) + { + compare_start = 1; + diff = expected_value - received_value; + } + received_value = (received_value + diff)&0xFFFFFF; + +#if 1 + + if (expected_value != received_value) + { + if(!error_cnt) + error_ts_start = (timestamp + c); + else + { + if (looploop < 32) + printf("%d - %d != %d - ts %d - raw 0x%x - diff %d\n", + looploop, + expected_value, received_value, + (timestamp + c), ((uint32_t *)(rxp[0]))[c], + diff); + looploop++; + } + + error_cnt++; + + if(!(error_cnt%102400)) + printf(" -> error detected : cnt=%d - start=%ld - stop=... diff=%d\n", + error_cnt, + error_ts_start, + diff); + + } + else + { + if(error_cnt) + { + printf(" -> error detected : cnt=%d - start=%ld - stop=%ld\n\n", + error_cnt, + error_ts_start, + (timestamp + c) ); + looploop=0; + } + error_cnt=0; + } +#endif +#endif + +// DEBUG mode 0 +#if 0 + received_value = ((uint32_t *)(rxp[0]))[c]; + received_value = ((received_value)&0xFFF) + ((received_value>>4)&0xFFF000); + received_value = (received_value&0xFFFFFF); + if (compare_start == 0) + { + compare_start = 1; + expected_value = received_value; + } + else + { + expected_value++; + expected_value = (expected_value&0xFFFFFF); + } + + if (expected_value != received_value) + { + if(!error_cnt) + error_ts_start = (timestamp + c); + error_cnt++; + } + else + { + if(error_cnt) + { + printf(" -> error detected : cnt=%d - start=%ld - stop=%ld\n\n", + error_cnt, + error_ts_start, + (timestamp + c) ); + } + error_cnt=0; + } + + + +// if (expected_value != received_value) +// { +// printf("%d -> %d != %d (ts+c=%ld)(raw=0x%08x)\n", +// looploop, +// expected_value, received_value, +// (timestamp + c), +// ((uint32_t *)(rxp[0]))[c] ); +// +// if (received_value) +// expected_value = received_value; +// } +#endif + + } + } + } + + printf("HwLat Application returns !!!\n"); + fflush(stdout); + sleep(1); + + + printf("\n"); + rf_device.trx_end_func( &rf_device ); + + sleep(1); + free(sendbuff[0]); + free(sendbuff); + free(recvbuff[0]); + free(recvbuff); + + exit(0); + + + + return(0); + + + +// puts( "* Frequency modification test" ); +// rf_device.trx_set_freq_func( &rf_device, &openair0_cfg[0], 0 ); + +// puts( "* Gain modification test" ); +// rf_device.trx_set_gains_func( &rf_device, &openair0_cfg[0] ); // NOT working (cf. initialization) + +//#if LTE_UE +// sleep(1); + GET_TIME_VAL(0); + for (i = 0; i < trx_read_cnt; i++) + { + printf("\n"); + ret = rf_device.trx_read_func( &rf_device, ×tamp, rxp, nsamp, antenna_id ); + printf("* timestamp=%ld\n", timestamp); +#if 1 + for (j = 0; j < nsamp; j++) + { + if ( ((uint32_t *)rxp[0])[j] != ((expected_value + j + timestamp)%307200) ) + { + err_cnt++; + printf("rxp[%06d]=0x%08x (expected 0x%08lx)\n", j, ((uint32_t *)rxp[0])[j], ((expected_value + j + timestamp)%307200) ); + } + if (err_cnt >= 128) + { + printf("Error: more than 128 expected value failed !\n"); + i = (trx_read_cnt - 1); + j = nsamp; + break; + } + } + //expected_value = (expected_value + nsamp)%307200; + expected_value = (expected_value)%307200; +#endif + } + GET_TIME_VAL(1); +//#endif + +/* ********** ********** */ +/* RIFFA_CHANNEL_DATA1 */ +/* ********** ********** */ +#if RIFFA_CHANNEL_DATA1 + +// rf_device.trx_get_stats_func( &rf_device ); + + rf_device.trx_end_func( &rf_device ); + + printf("\n* rf_device.trx_read_func(%d) x %d: %.6lf s\n\n", nsamp, i, ((TIME_VAL_TO_MS(1) - TIME_VAL_TO_MS(0)))/1000.0 ); + +// rf_device.trx_get_stats_func( &rf_device ); + +#if 0 + for (i = 0; i < nsamp; i++) + { +// if ( ((uint32_t *)rxp[0])[i] != i) +// { + err_cnt++; + printf("rxp[%06d]=0x%08x (expected 0x%08x)\n", i, ((uint32_t *)rxp[0])[i], i); +// } +// if (err_cnt > 256) +// { +// i = 307200; +// break; +// } + } +#endif +// for (i = 1024-32; i < 1024+32; i++) +// { +//// if ( ((uint32_t *)rxp[0])[i] != i) +//// { +// err_cnt++; +// printf("rxp[%06d]=0x%08x (expected 0x%08x)\n", i, ((uint32_t *)rxp[0])[i], i); +//// } +// if (err_cnt > 256) +// { +// i = 307200; +// break; +// } +// } + printf("RIFFA CHANNEL DATA1 done !!!\n"); + sleep(1); + return(0); +#endif +/* ********** ********** */ +/* RIFFA_CHANNEL_DATA1 */ +/* ********** ********** */ + + + + timestamp = 0; + ret = rf_device.trx_write_func( &rf_device, timestamp, (void**)sendbuff, nsamp, antenna_id, false ); + printf("* rf_device.trx_write_func returns %d\n", ret); + + sleep(1); + + nsamp = 30720; + numIter = 100000; + for ( c = 0; c < numIter; c++ ) + { + fpga_loop ++; + if ( !(fpga_loop % 1000) ) + { + printf("\rtest loop %d / %d", fpga_loop, numIter); + fflush(stdout); + } + +// printf("* TEST : %08d\n", (c+1)); +// measure_time( &rf_device, &start, &stop, &tx_stats, true, 10 ); +// ret = rf_device.trx_write_func( &rf_device, timestamp, (void**)sendbuff, nsamp, antenna_id, false ); +// printf("* rf_device.trx_write_func returns %d\n", ret); +// measure_time( &rf_device, &start, &stop, &tx_stats, false, 10 ); + +// sleep(1); + +// measure_time( &rf_device, &start, &stop, &tx_stats, true, 10 ); + ret = rf_device.trx_read_func( &rf_device, ×tamp, (void**)recvbuff, nsamp, antenna_id ); +// measure_time( &rf_device, &start, &stop, &tx_stats, false, 10 ); + + // Check the data + if (ret > 0) + { +/* ********** ********** */ +/* RIFFA_CHANNEL_TESTER */ +/* ********** ********** */ +#if RIFFA_CHANNEL_TESTER + failure = 0; + for (i = 0; i < ret; i++) + { + if ( ((i%1024) == 0) || ((i%1024) == 1) || ((i%1024) == 2) || ((i%1024) == 3) ) + { + if ( (recvbuff[0])[i] != (1020 + ((i%1024)+1)) ) + { + printf("* ERROR (buff[0])[%d]: %d, expected %d\n", i, (uint32_t)(recvbuff[0])[i], ((i%1024)+1) ); + failure = 1; + } + } + else if ( (recvbuff[0])[i] != ((i%1024)+1) ) + { + printf("* ERROR (buff[0])[%d]: %d, expected %d\n", i, (uint32_t)(recvbuff[0])[i], ((i%1024)+1) ); + failure = 1; + } + else + { + printf("* DONE (buff[0])[%d]: %d, expected %d\n", i, (uint32_t)(recvbuff[0])[i], ((i%1024)+1) ); + } + if(failure) + break; + } + if (failure) + printf("* ERROR recv %08d checked FAILURE ret=%d\n", (c+1), ret); + else + { +// printf("* DONE recv %08d checked SUCCESSFULLY ret=%d\n", (c+1), ret); + } +#endif +/* ********** ********** */ +/* RIFFA_CHANNEL_TESTER2*/ +/* ********** ********** */ +#if RIFFA_CHANNEL_TESTER2 +// printf("* ret=%d timestamp=%ld (%ld)\n", ret, timestamp, (timestamp%307200)); + failure = 0; + for (i = 0; i < ret; i++) + { +// printf("* (recvbuff[0])[%d]: %d\n", i, (uint32_t)(recvbuff[0])[i]); +// printf("* timestamp+(i/1024+1)*1024 - 3 + i%1024: %d\n", (timestamp-nsamp+(i/1024+1)*1024 - 3 + i%1024)%307200 ); + expected_value = ((((i%1024)+1)/*>>4*/)&0x00000FFF); + if ( ((i%1024) == 0) || ((i%1024) == 1) || ((i%1024) == 2) || ((i%1024) == 3) ) + { + expected_value = ((((timestamp-nsamp+(i/1024+1)*1024 - 3 + i%1024))%307200)); + if ( (recvbuff[0])[i] != expected_value) + { + if ( (expected_value == 0) && ((recvbuff[0])[i] != 4915200) ) + { + printf("* ERROR (buff[0])[%d]: %d, expected %d\n", i, (uint32_t)(recvbuff[0])[i], expected_value ); + failure = 1; + } + if ( (expected_value == 0) && ((recvbuff[0])[i] == 4915200) ) + { +// printf("* DONE loop in circular buffer\n"); + } + } + } + else if ( (recvbuff[0])[i] != expected_value ) + { + printf("* ERROR (buff[0])[%d]: %d, expected %d\n", i, (uint32_t)(recvbuff[0])[i], ((i%1024)+1) ); + failure = 1; + } + else + { +// printf("* DONE (buff[0])[%d]: %d, expected %d\n", i, (uint32_t)(recvbuff[0])[i], ((i%1024)+1) ); + } +// if(failure) +// break; + } + if (failure) + printf("* ERROR recv %08d checked FAILURE ret=%d\n", (c+1), ret); + else + { +// printf("* DONE recv %08d checked SUCCESSFULLY ret=%d\n", (c+1), ret); + } +#endif +#if LOOPBACK + +#endif + } + else + { + printf("* ERROR rf_device.trx_read_func returns %d\n", ret); + } + + } + printf("\n"); + rf_device.trx_end_func( &rf_device ); + + sleep(1); + free(sendbuff[0]); + free(sendbuff); + free(recvbuff[0]); + free(recvbuff); + + exit(0); + +// END IS HERE ! + + rf_device.trx_set_freq_func(&rf_device,&openair0_cfg[0],0); + + if (rf_device.trx_start_func(&rf_device) != 0 ) { + printf("Could not start the device\n"); + oai_exit=1; + } + + while(!oai_exit){ + + rxp[0] = (void*)&rxdata[0][sub_frame*nb_sample_per_tti]; + + readBlockSize = rf_device.trx_read_func( &rf_device, + ×tamp, + rxp, + nb_sample_per_tti, + 0); + + if ( readBlockSize != nb_sample_per_tti ) + oai_exit = 1; + + sub_frame++; + sub_frame%=10; + + if( sub_frame == 0) + frame_rx++; + + saif_meas(frame_rx, sub_frame); + } + + return(0); +} diff --git a/targets/RT/USER/lte-hwlat2.c b/targets/RT/USER/lte-hwlat2.c new file mode 100644 index 0000000000000000000000000000000000000000..67761be9a7fcfb796dfbfe977b1865a519a8dd11 --- /dev/null +++ b/targets/RT/USER/lte-hwlat2.c @@ -0,0 +1,1282 @@ +/* + * 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 + */ + + +/* ************************************************************************************************* + + USER GUIDE + + 1 - CONFIGURE TEST SESSION + see TESTS PARAMETERS section below + + 2 - COMPILATION CMD LINE (same as openair compilation) + - NO AVX SUPPORT + /usr/bin/cc -msse4.1 -mssse3 -std=gnu99 -Wall -Wstrict-prototypes -fno-strict-aliasing -rdynamic -funroll-loops -Wno-packed-bitfield-compat -fPIC -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_FCNTL_H=1 -DHAVE_ARPA_INET_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_SOCKET_H=1 -DHAVE_STRERROR=1 -DHAVE_SOCKET=1 -DHAVE_MEMSET=1 -DHAVE_GETTIMEOFDAY=1 -DHAVE_STDLIB_H=1 -DHAVE_MALLOC=1 -DHAVE_LIBSCTP -g -DMALLOC_CHECK_=3 -O2 -o lte-hwlat-test lte-hwlat2.c -lrt -lpthread -lm -ldl + - AVX2 Support + /usr/bin/cc -mavx2 -msse4.1 -mssse3 -std=gnu99 -Wall -Wstrict-prototypes -fno-strict-aliasing -rdynamic -funroll-loops -Wno-packed-bitfield-compat -fPIC -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_FCNTL_H=1 -DHAVE_ARPA_INET_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_SOCKET_H=1 -DHAVE_STRERROR=1 -DHAVE_SOCKET=1 -DHAVE_MEMSET=1 -DHAVE_GETTIMEOFDAY=1 -DHAVE_STDLIB_H=1 -DHAVE_MALLOC=1 -DHAVE_LIBSCTP -g -DMALLOC_CHECK_=3 -O2 -o lte-hwlat-test lte-hwlat2.c -lrt -lpthread -lm -ldl + + + 3 - RUN + sudo cset shield --force --kthread on -c 1-3 // for 4 cores + sudo cset shield --force --kthread on -c 1-7 // for 8 cores + sudo cset shield ./lte-hwlat-test + + 4 - remove cset shield + sudo cset shield --reset + + ***************************************************************************************************/ + +/* ************************************************************************************************* + * TESTS PARAMETERS + */ +#define HWLAT_LOOP_CNT 1000000 /* measurment loop count for each thread*/ +#define HWLAT_TTI_SLEEP_US 250 /* usleep duration -> IQ capture simulation (in µ seconds) */ + +#define RX_NB_TH 6 + +#define CALIB_RT_INTRUMENTATION 0 + +/* Laurent Thpmas instrumentation -> see openair2/UTIL/LOG/log.h for full implementation + -> This is a copy and paste implementation in this file for a self contained source */ +#define INSTRUMENTATION_LT_RDTSC 1 +/* SYRTEM rdtsc instrumentation implementation (see below for more infaormation) */ +#define INSTRUMENTATION_SYR_RDTSC 2 +/* SYRTEM instrumentation using clock_gettime MONOTONIC */ +#define INSTRUMENTATION_SYR_CLOCK_MONO 3 +/* SYRTEM instrumentation using clock_gettime REALTIME */ +#define INSTRUMENTATION_SYR_CLOCK_REALTIME 4 + +#define HWLAT_INSTRUMENTATION INSTRUMENTATION_LT_RDTSC + + +/* Statistics histogram output */ +#define HISTOGRAM_MIN_VALUE 0 +#define HISTOGRAM_MAX_VALUE 2000 +#define HISTOGRAM_STEP 1 +#define HISTOGRAM_SIZE ( ( ( HISTOGRAM_MAX_VALUE - HISTOGRAM_MIN_VALUE ) / HISTOGRAM_STEP ) + 1 ) + + + +/* *************************************************************************************************/ + + +/* + * INCLUDES + */ +#define _GNU_SOURCE +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <errno.h> +#include <stdint.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <pthread.h> +#include <linux/kernel.h> +#include <linux/types.h> +#include <syscall.h> +#include <math.h> +#include <sched.h> +#include <sys/ioctl.h> +#include <sys/types.h> +#include <sys/mman.h> +#include <sched.h> +#include <linux/sched.h> +#include <signal.h> +#include <execinfo.h> +#include <getopt.h> +#include <sys/sysinfo.h> +#include <unistd.h> +#include <sys/syscall.h> /* For SYS_xxx definitions */ +#ifndef __STDC_FORMAT_MACROS +#define __STDC_FORMAT_MACROS +#endif +#include <inttypes.h> + + +/* From rt_wrapper.h +****************************************************************************************/ +#define gettid() syscall(__NR_gettid) // for gettid + +/* From common/utils/itti/assertions.h +****************************************************************************************/ +# define display_backtrace() + +#define _Assert_Exit_ \ +{ \ + fprintf(stderr, "\nExiting execution\n"); \ + display_backtrace(); \ + fflush(stdout); \ + fflush(stderr); \ + exit(EXIT_FAILURE); \ +} + +#define _Assert_(cOND, aCTION, fORMAT, aRGS...) \ +do { \ + if (!(cOND)) { \ + fprintf(stderr, "\nAssertion ("#cOND") failed!\n" \ + "In %s() %s:%d\n" fORMAT, \ + __FUNCTION__, __FILE__, __LINE__, ##aRGS); \ + aCTION; \ + } \ +} while(0) + +#define AssertFatal(cOND, fORMAT, aRGS...) _Assert_(cOND, _Assert_Exit_, fORMAT, ##aRGS) + + +/* From "openair1/PHY/TOOLS/time_meas.h" +****************************************************************************************/ +double cpu_freq_GHz; + + +typedef struct { + + long long in; + long long diff; + long long diff_now; + long long p_time; /*!< \brief absolute process duration */ + long long diff_square; /*!< \brief process duration square */ + long long max; + int trials; + int meas_flag; +} time_stats_t; + +static inline unsigned long long rdtsc_oai(void) __attribute__((always_inline)); +static inline unsigned long long rdtsc_oai(void) +{ + unsigned long long a, d; + __asm__ volatile ("rdtsc" : "=a" (a), "=d" (d)); + return (d<<32) | a; +} + +double get_cpu_freq_GHz(void); + +static inline void reset_meas(time_stats_t *ts) { + + ts->trials=0; + ts->diff=0; + ts->diff_now=0; + ts->p_time=0; + ts->diff_square=0; + ts->max=0; + ts->meas_flag=0; + +} + +double estimate_MHz_syr(void); +static __inline__ uint64_t pickCyclesStart(void); +static __inline__ uint64_t pickCyclesStop(void); + + +/* From "openair2/UTIL/LOG/log.h" +****************************************************************************************/ +extern double cpuf; +extern double cpu_mhz_syr; + + +static __inline__ uint64_t rdtsc(void) { + uint64_t a, d; + __asm__ volatile ("rdtsc" : "=a" (a), "=d" (d)); + return (d<<32) | a; +} + +typedef struct m { + uint64_t iterations; + uint64_t sum; + uint64_t maxArray[11]; +} Meas; + +static inline void printMeas(char * txt, Meas *M, int period) { + if (M->iterations%period == 0 ) { + char txt2[512]; + sprintf(txt2,"%s avg=%" PRIu64 " iterations=%" PRIu64 " max=%" + PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 "\n", + txt, + M->sum/M->iterations, + M->iterations, + M->maxArray[1],M->maxArray[2], M->maxArray[3],M->maxArray[4], M->maxArray[5], + M->maxArray[6],M->maxArray[7], M->maxArray[8],M->maxArray[9],M->maxArray[10]); +// SYRTEM : just use printf do not include all LOG_X for this test +//#if DISABLE_LOG_X + printf("%s",txt2); +//#else +// LOG_W(PHY, "%s",txt2); +//#endif + } +} + +static inline int cmpint(const void* a, const void* b) { + uint64_t* aa=(uint64_t*)a; + uint64_t* bb=(uint64_t*)b; + return (int)(*aa-*bb); +} + +static inline uint64_t updateTimes(uint64_t start, Meas *M, int period, char * txt) { + if (start!=0) { + uint64_t end=rdtsc(); + long long diff=(end-start)/(cpuf*1000); + M->maxArray[0]=diff; + M->sum+=diff; + M->iterations++; + qsort(M->maxArray, 11, sizeof(uint64_t), cmpint); +// printMeas(txt,M,period); // SYRTEM : Printed only a the end of the measurment loop + return diff; + } + return 0; +} + +static inline uint64_t updateTimes_syr(uint64_t start, Meas *M, int period, char * txt) { + if (start!=0) { +// uint64_t end=rdtsc(); + uint64_t end=pickCyclesStop(); + long long diff=(long long)((double)(end-start)/(cpu_mhz_syr)); +// long long diff=(end-start)/(cpuf*1000); + M->maxArray[0]=diff; + M->sum+=diff; + M->iterations++; + qsort(M->maxArray, 11, sizeof(uint64_t), cmpint); +// printMeas(txt,M,period); // SYRTEM : Printed only a the end of the measurment loop + return diff; + } + return 0; +} + + + + +#define initRefTimes(a) static __thread Meas a= {0} +#define pickTime(a) uint64_t a=rdtsc() +#define pickTime_syr(a) uint64_t a=pickCyclesStart() +#define readTime(a) a + + + + + + +/* + * DEFINES + */ + +#define TIMESPEC_TO_DOUBLE_US( t ) ( ( (double)t.tv_sec * 1000000 ) + ( (double)t.tv_nsec / 1000 ) ) + +typedef struct histo_time { + double max; + unsigned int count; +} histo_time_t; + +static void measure_time ( struct timespec *start, struct timespec *stop, uint8_t START, uint16_t PRINT_INTERVAL ); +static struct timespec get_timespec_diff( struct timespec *start, struct timespec *stop ); +void histogram_save_in_csv( histo_time_t *histo , char *file_prefix); +histo_time_t *histogram_init( histo_time_t *histo ); +void histogram_store_value( histo_time_t *histo, double value ); + + +#define FIFO_PRIORITY 40 + + + +#define true 1 +#define false 0 + + + + +/* + * STRUCTURES + */ + + +/* stub of UE_rxtx_proc full structure in openair1/PHY/defs.h +*/ +typedef struct UE_rxtx_proc { + int instance_cnt_rxtx; + pthread_t pthread_rxtx; + pthread_cond_t cond_rxtx; + pthread_mutex_t mutex_rxtx; + + + int sub_frame_start; + int sub_frame_step; + unsigned long long gotIQs; + + + unsigned long syr_rdtsc_rxtx_th_unlock_iteration; + uint64_t syr_rdtsc_ue_th_got_iq; + double syr_rdtsc_rxtx_th_unlock; + double syr_rdtsc_rxtx_th_unlock_max; + double syr_rdtsc_rxtx_th_unlock_mean; + double syr_rdtsc_rxtx_th_unlock_min; + histo_time_t *syr_rdtsc_rxtx_th_unlock_histogram; + +} UE_rxtx_proc_t; + + + +/* this structure is used to pass both UE phy vars and + * proc to the function UE_thread_rxn_txnp4 + */ +struct rx_tx_thread_data { + /* PHY_VARS_UE *UE; */ // UE phy vars not used for this test + UE_rxtx_proc_t *proc; // We use a stub of rxtx_proc see definition above +}; + + +// ODD / EVEN Scheduling +#if 0 +typedef struct threads_s { + int iq; + int odd; + int even; +} threads_t; +threads_t threads = { -1, -1, -1 }; // Core number for each thread (iq=3, even=2, odd=1) +#endif + +// SLOT 0 / SLOT 1 parallelization +typedef struct threads_s { + int iq; + int one; + int two; + int three; + int four; + int five; + int six; + int slot1_proc_one; + int slot1_proc_two; + int slot1_proc_three; +} threads_t; +threads_t threads= {7,6,5,4,3,2,1,-1,-1,-1}; + +/* + * FUNCTIONS DEFINITION + */ + +void *UE_thread(void *arg); +void init_UE(int nb_inst); + + + +/* + * GLOBALS VARIABLES + */ + +volatile int oai_exit = 0; +int th_count = 0; +double cpuf; +double cpu_mhz_syr; + + + + + + + +pthread_t pthread_ue; +pthread_attr_t attr_ue; + +UE_rxtx_proc_t **rxtx_proc; + +struct timespec even_start, even_stop; +struct timespec odd_start, odd_stop; + +histo_time_t *th_wake_histogram; + + +/* + * FUNCTIONS + */ + + + +void exit_fun(const char* s) { + if ( s != NULL ) { + printf("%s %s() Exiting OAI softmodem: %s\n",__FILE__, __FUNCTION__, s); + } + + oai_exit = 1; +} + + + + +void init_thread(int sched_runtime, int sched_deadline, int sched_fifo, cpu_set_t *cpuset, char * name) { + +#ifdef DEADLINE_SCHEDULER + if (sched_runtime!=0) { + struct sched_attr attr= {0}; + attr.size = sizeof(attr); + attr.sched_policy = SCHED_DEADLINE; + attr.sched_runtime = sched_runtime; + attr.sched_deadline = sched_deadline; + attr.sched_period = 0; + AssertFatal(sched_setattr(0, &attr, 0) == 0, + "[SCHED] %s thread: sched_setattr failed %s \n", name, strerror(errno)); + LOG_I(HW,"[SCHED][eNB] %s deadline thread %lu started on CPU %d\n", + name, (unsigned long)gettid(), sched_getcpu()); + } + +#else + if (CPU_COUNT(cpuset) > 0) + AssertFatal( 0 == pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), cpuset), ""); + struct sched_param sp; + sp.sched_priority = sched_fifo; + AssertFatal(pthread_setschedparam(pthread_self(),SCHED_FIFO,&sp)==0, + "Can't set thread priority, Are you root?\n"); + /* Check the actual affinity mask assigned to the thread */ + cpu_set_t *cset=CPU_ALLOC(CPU_SETSIZE); + if (0 == pthread_getaffinity_np(pthread_self(), CPU_ALLOC_SIZE(CPU_SETSIZE), cset)) { + char txt[512]={0}; + for (int j = 0; j < CPU_SETSIZE; j++) + if (CPU_ISSET(j, cset)) + sprintf(txt+strlen(txt), " %d ", j); + printf("CPU Affinity of thread %s is %s\n", name, txt); + } + CPU_FREE(cset); +#endif + + // Lock memory from swapping. This is a process wide call (not constraint to this thread). + mlockall(MCL_CURRENT | MCL_FUTURE); + pthread_setname_np( pthread_self(), name ); + +// SYRTEM : Synchronization thread is not simulated -> just ignore this part of code +// // LTS: this sync stuff should be wrong +// printf("waiting for sync (%s)\n",name); +// pthread_mutex_lock(&sync_mutex); +// printf("Locked sync_mutex, waiting (%s)\n",name); +// while (sync_var<0) +// pthread_cond_wait(&sync_cond, &sync_mutex); +// pthread_mutex_unlock(&sync_mutex); + printf("started %s as PID: %ld\n",name, gettid()); +} + +void init_UE(int nb_inst) +{ + int inst; + for (inst=0; inst < nb_inst; inst++) { + // UE->rfdevice.type = NONE_DEV; +// SYRTEM : we use a stub of phy_var_ue +// PHY_VARS_UE *UE = PHY_vars_UE_g[inst][0]; +// AssertFatal(0 == pthread_create(&UE->proc.pthread_ue, &UE->proc.attr_ue, UE_thread, (void*)UE), ""); + AssertFatal( 0 == pthread_create( &pthread_ue, &attr_ue, UE_thread, NULL ), "" ); + } + + printf("UE threads created by %ld\n", gettid()); +} + + +// SYRTEM - UE synchronization thread is not used in this latency test program +//static void *UE_thread_synch(void *arg) { +// ... +//} + + +// SYRTEM - Stub of UE_thread_rxn_txnp4 +// -> No DSP scheduled +// -> Only thread initialization and thread wake up are kept + +static void *UE_thread_rxn_txnp4(void *arg){ + static __thread int UE_thread_rxtx_retval; + struct rx_tx_thread_data *rtd = arg; + UE_rxtx_proc_t *proc = rtd->proc; + + proc->instance_cnt_rxtx=-1; + + char threadname[256]; + sprintf(threadname,"UE_%d_proc_%d", 0, proc->sub_frame_start); + + cpu_set_t cpuset; + CPU_ZERO(&cpuset); + + if ( (proc->sub_frame_start)%RX_NB_TH == 0 && threads.one != -1 ) + CPU_SET(threads.one, &cpuset); + if ( (proc->sub_frame_start)%RX_NB_TH == 1 && threads.two != -1 ) + CPU_SET(threads.two, &cpuset); + if ( (proc->sub_frame_start)%RX_NB_TH == 2 && threads.three != -1 ) + CPU_SET(threads.three, &cpuset); + if ( (proc->sub_frame_start)%RX_NB_TH == 3 && threads.four != -1 ) + CPU_SET(threads.four, &cpuset); + if ( (proc->sub_frame_start)%RX_NB_TH == 4 && threads.five != -1 ) + CPU_SET(threads.five, &cpuset); + if ( (proc->sub_frame_start)%RX_NB_TH == 5 && threads.six != -1 ) + CPU_SET(threads.six, &cpuset); + //CPU_SET(threads.three, &cpuset); + init_thread(900000,1000000 , FIFO_PRIORITY-1, &cpuset, + threadname); + + + proc->syr_rdtsc_rxtx_th_unlock_iteration=0; + proc->syr_rdtsc_rxtx_th_unlock_max=0; + proc->syr_rdtsc_rxtx_th_unlock_mean=0; + proc->syr_rdtsc_rxtx_th_unlock_min=1000; + proc->syr_rdtsc_rxtx_th_unlock_histogram = NULL; + proc->syr_rdtsc_rxtx_th_unlock_histogram = histogram_init (proc->syr_rdtsc_rxtx_th_unlock_histogram); + + while (!oai_exit) { + if (pthread_mutex_lock(&proc->mutex_rxtx) != 0) { + printf("[SCHED][UE] error locking mutex for UE RXTX\n" ); + exit_fun("nothing to add"); + } + while (proc->instance_cnt_rxtx < 0) { + // most of the time, the thread is waiting here + pthread_cond_wait( &proc->cond_rxtx, &proc->mutex_rxtx ); + } + if (pthread_mutex_unlock(&proc->mutex_rxtx) != 0) { + printf("[SCHED][UE] error unlocking mutex for UE RXn_TXnp4\n" ); + exit_fun("nothing to add"); + } + + + proc->syr_rdtsc_rxtx_th_unlock = (double)(pickCyclesStop()-proc->syr_rdtsc_ue_th_got_iq )/cpu_mhz_syr; + + proc->syr_rdtsc_rxtx_th_unlock_iteration++; + + proc->syr_rdtsc_rxtx_th_unlock_mean += proc->syr_rdtsc_rxtx_th_unlock; + if ( proc->syr_rdtsc_rxtx_th_unlock_max < proc->syr_rdtsc_rxtx_th_unlock ) + proc->syr_rdtsc_rxtx_th_unlock_max = proc->syr_rdtsc_rxtx_th_unlock; + if ( proc->syr_rdtsc_rxtx_th_unlock_min > proc->syr_rdtsc_rxtx_th_unlock ) + proc->syr_rdtsc_rxtx_th_unlock_min = proc->syr_rdtsc_rxtx_th_unlock; + histogram_store_value( proc->syr_rdtsc_rxtx_th_unlock_histogram, proc->syr_rdtsc_rxtx_th_unlock ); + + + if (pthread_mutex_lock(&proc->mutex_rxtx) != 0) { + printf("[SCHED][UE] error locking mutex for UE RXTX\n" ); + exit_fun("noting to add"); + } + proc->instance_cnt_rxtx--; + if (pthread_mutex_unlock(&proc->mutex_rxtx) != 0) { + printf("[SCHED][UE] error unlocking mutex for UE RXTX\n" ); + exit_fun("noting to add"); + } + } + +// thread finished + free(arg); + return &UE_thread_rxtx_retval; +} + + + + +void *UE_thread(void *arg) { + + int i = 0; + int hw_loop_cnt = 0; + + int nb_threads = RX_NB_TH; + char threadname[128]; + cpu_set_t cpuset; + struct rx_tx_thread_data *rtd; + UE_rxtx_proc_t *proc; + + CPU_ZERO( &cpuset ); + + if ( threads.iq != -1 ) + CPU_SET( threads.iq, &cpuset ); + init_thread( 100000, 500000, FIFO_PRIORITY, &cpuset, "HDW Threads" ); + + sprintf( threadname, "Main UE %d", 0 ); + pthread_setname_np( pthread_self(), threadname ); + + +// init_UE_threads(UE) + pthread_attr_init( &attr_ue ); + pthread_attr_setstacksize( &attr_ue, 8192 );//5*PTHREAD_STACK_MIN); + + for ( i = 0; i < nb_threads; i++ ) { + + printf("\n"); + + rtd = calloc( 1, sizeof( struct rx_tx_thread_data ) ); + if ( rtd == NULL ) + abort(); + + rtd->proc = rxtx_proc[i]; // &UE->proc.proc_rxtx[i]; + + pthread_mutex_init( &rxtx_proc[i]->mutex_rxtx ,NULL ); // pthread_mutex_init( &UE->proc.proc_rxtx[i].mutex_rxtx,NULL ); + pthread_cond_init( &rxtx_proc[i]->cond_rxtx, NULL ); // pthread_cond_init(&UE->proc.proc_rxtx[i].cond_rxtx,NULL); + rtd->proc->sub_frame_start=i; + rtd->proc->sub_frame_step=nb_threads; + printf("Init_UE_threads rtd %d proc %d nb_threads %d i %d\n",rtd->proc->sub_frame_start, rxtx_proc[i]->sub_frame_start,nb_threads, i); + pthread_create( &rxtx_proc[i]->pthread_rxtx, NULL, UE_thread_rxn_txnp4, rtd ); // pthread_create( &UE->proc.proc_rxtx[i].pthread_rxtx, NULL, UE_thread_rxn_txnp4, rtd); + + usleep(1000); + + } +// init_UE_threads(UE) + + + + int sub_frame=-1; + while ( !oai_exit ) { + + sub_frame++; + sub_frame %= 10; + + proc = rxtx_proc[hw_loop_cnt%RX_NB_TH]; + + // Simulate IQ reception + usleep( HWLAT_TTI_SLEEP_US ); + + proc->syr_rdtsc_ue_th_got_iq = pickCyclesStart(); + + AssertFatal(pthread_mutex_lock(&proc->mutex_rxtx) ==0,""); + + proc->instance_cnt_rxtx++; + if ( proc->instance_cnt_rxtx == 0 ) { + if ( pthread_cond_signal( &proc->cond_rxtx) != 0 ) { + exit_fun( "nothing to add" ); + } + } else { + if ( proc->instance_cnt_rxtx > 2 ) + exit_fun( "instance_cnt_rxtx > 2" ); + } + + AssertFatal( pthread_cond_signal( &proc->cond_rxtx ) == 0 ,"" ); + AssertFatal(pthread_mutex_unlock(&proc->mutex_rxtx) ==0,""); + + + /* Do not go indefinitely */ + hw_loop_cnt++; + + if ( hw_loop_cnt%1000 == 0 ) + { + printf("\r%d/%d",hw_loop_cnt,HWLAT_LOOP_CNT*RX_NB_TH); + fflush(stdout); + } + + if (hw_loop_cnt >= HWLAT_LOOP_CNT*RX_NB_TH) + { + printf("\n\n"); + for (i=0 ; i<RX_NB_TH ; i++) + { + proc = rxtx_proc[i]; + pthread_getname_np(proc->pthread_rxtx,threadname,128 ); + printf("RxTX Thread unlock latency on thread %s (it. %ld) (us) : max=%8.3f - mean=%8.3f - min=%8.3f\n", + threadname, + proc->syr_rdtsc_rxtx_th_unlock_iteration, + proc->syr_rdtsc_rxtx_th_unlock_max, + proc->syr_rdtsc_rxtx_th_unlock_mean/proc->syr_rdtsc_rxtx_th_unlock_iteration, + proc->syr_rdtsc_rxtx_th_unlock_min); + + histogram_save_in_csv(proc->syr_rdtsc_rxtx_th_unlock_histogram, threadname ); + + } + printf("\n\n"); + oai_exit = 1; + } + + } // while !oai_exit + + oai_exit = 1; + + return NULL; +} + +#define CALIB_LOOP_CNT 1000000 //2000000000 +#define CALIB_LOOP_REPORT_PERIOD 1000 +#define CALIB_LOOP_UP_THRESHOLD 20 // 20 -> for NG Intel flat model +#define CALIB_USLEEP 250 + +int main( void ) +{ + + int i; + + +#if CALIB_RT_INTRUMENTATION + uint32_t calib_loop_count; + + + uint64_t lt_overhead_cur; + uint64_t lt_overhead_min; + uint64_t lt_overhead_max; + uint64_t lt_overhead_mean; + histo_time_t *lt_overhead_histogram = NULL; + + uint64_t lt_syr_overhead_cur; + uint64_t lt_syr_overhead_min; + uint64_t lt_syr_overhead_max; + uint64_t lt_syr_overhead_mean; + histo_time_t *lt_syr_overhead_histogram = NULL; + + double syr_rdtsc_overhead_cur; + double syr_rdtsc_overhead_min; + double syr_rdtsc_overhead_max; + double syr_rdtsc_overhead_mean; + histo_time_t *syr_rdtsc_overhead_histogram = NULL; + + double syr_clock_gettime_overhead_cur; + double syr_clock_gettime_overhead_min; + double syr_clock_gettime_overhead_max; + double syr_clock_gettime_overhead_mean; + histo_time_t *syr_clock_gettime_overhead_histogram = NULL; + + + uint64_t cycles_start; + uint64_t cycles_stop; + + uint64_t cycles_diff; + uint64_t cycles_diff_max = 0; + + + struct timespec start; + struct timespec stop; +#endif + + cpuf = get_cpu_freq_GHz(); + cpu_mhz_syr = estimate_MHz_syr(); + + printf("\n\ncpuf %f - cpu_mhz_syr %f\n\n", cpuf, cpu_mhz_syr); + +#if CALIB_RT_INTRUMENTATION + + /* ********************************************************************************************** */ + /* CALIBRATION */ + /* ********************************************************************************************** */ + + /* ************************************************************* + Laurent Thomas instrumentation overhead + */ + printf("\nCalibrating OAI Realtime Instrumentation (Laurent Thomas imp.)\n"); + calib_loop_count = CALIB_LOOP_CNT; + initRefTimes(lt_instru_calib); // Laurent Thomas realtime instrumentation calibration measurments + lt_overhead_min = 1000; + lt_overhead_max = 0; + lt_overhead_mean = 0; + lt_overhead_histogram = histogram_init( lt_overhead_histogram ); + while(calib_loop_count) + { + pickTime(lt_start); + +// asm volatile(""); // Nop instruction + usleep(CALIB_USLEEP); + + lt_overhead_cur = updateTimes( readTime(lt_start), + <_instru_calib, + CALIB_LOOP_CNT, + "Laurent Thomas realtime instrumentation calibration measurments"); + + lt_overhead_mean += lt_overhead_cur; + if ( lt_overhead_max < lt_overhead_cur ) + lt_overhead_max = lt_overhead_cur; + if ( lt_overhead_min > lt_overhead_cur ) + lt_overhead_min = lt_overhead_cur; + histogram_store_value( lt_overhead_histogram, (double)lt_overhead_cur ); + + if ( calib_loop_count%CALIB_LOOP_REPORT_PERIOD == 0 ) + { + printf("\r%d/%d",calib_loop_count,CALIB_LOOP_CNT); + fflush(stdout); + } + + calib_loop_count--; + } + lt_overhead_mean = lt_overhead_mean/CALIB_LOOP_CNT; + +// printMeas("\nLaurent Thomas realtime instrumentation calibration measurments",<_instru_calib,CALIB_LOOP_CNT); + + + /* ************************************************************* + Laurent Thomas instrumentation overhead + */ + printf("\nCalibrating OAI Realtime Instrumentation - SYRTEM revisited\n"); + calib_loop_count = CALIB_LOOP_CNT; + initRefTimes(lt_instru_calib_syr); // Laurent Thomas realtime instrumentation calibration measurments + lt_syr_overhead_min = 1000; + lt_syr_overhead_max = 0; + lt_syr_overhead_mean = 0; + lt_syr_overhead_histogram = histogram_init( lt_syr_overhead_histogram ); + while(calib_loop_count) + { + pickTime_syr(lt_start_syr); + +// asm volatile(""); // Nop instruction + usleep(CALIB_USLEEP); + + lt_syr_overhead_cur = updateTimes_syr(readTime(lt_start_syr), <_instru_calib_syr, CALIB_LOOP_CNT, "Laurent Thomas realtime instrumentation calibration measurments (SYRTEM Update)"); + + lt_syr_overhead_mean += lt_syr_overhead_cur; + if ( lt_syr_overhead_max < lt_syr_overhead_cur ) + lt_syr_overhead_max = lt_syr_overhead_cur; + if ( lt_syr_overhead_min > lt_syr_overhead_cur ) + lt_syr_overhead_min = lt_syr_overhead_cur; + histogram_store_value( lt_syr_overhead_histogram, (double)lt_syr_overhead_cur ); + + if ( calib_loop_count%CALIB_LOOP_REPORT_PERIOD == 0 ) + { + printf("\r%d/%d",calib_loop_count,CALIB_LOOP_CNT); + fflush(stdout); + } + + calib_loop_count--; + } + lt_syr_overhead_mean = lt_syr_overhead_mean / CALIB_LOOP_CNT; + +// printMeas("\nLaurent Thomas realtime instrumentation calibration measurments (SYRTEM Update)",<_instru_calib_syr,CALIB_LOOP_CNT); + + + + /* ************************************************************* + SYRTEM RDTSC instrumentation overhead + */ + printf("\nCalibrating SYRTEM RDTSC Realtime Instrumentation\n"); + calib_loop_count = CALIB_LOOP_CNT; + syr_rdtsc_overhead_min = 1000; + syr_rdtsc_overhead_max = 0; + syr_rdtsc_overhead_mean = 0; + syr_rdtsc_overhead_histogram = histogram_init( syr_rdtsc_overhead_histogram ); + while(calib_loop_count) + { + + cycles_start = pickCyclesStart(); + +// asm volatile(""); // Nop instruction + usleep(CALIB_USLEEP); + + cycles_stop = pickCyclesStop(); + + cycles_diff = cycles_stop - cycles_start; + if(cycles_diff_max < cycles_diff) + cycles_diff_max = cycles_diff; + + syr_rdtsc_overhead_cur = (double)cycles_diff/cpu_mhz_syr; + + syr_rdtsc_overhead_mean += syr_rdtsc_overhead_cur; + if ( syr_rdtsc_overhead_max < syr_rdtsc_overhead_cur ) + syr_rdtsc_overhead_max = syr_rdtsc_overhead_cur; + if ( syr_rdtsc_overhead_min > syr_rdtsc_overhead_cur ) + syr_rdtsc_overhead_min = syr_rdtsc_overhead_cur; + histogram_store_value( syr_rdtsc_overhead_histogram, (double)syr_rdtsc_overhead_cur ); + + if ( calib_loop_count%CALIB_LOOP_REPORT_PERIOD == 0 ) + { + printf("\r%d/%d",calib_loop_count,CALIB_LOOP_CNT); + fflush(stdout); + } + + calib_loop_count--; + } + syr_rdtsc_overhead_mean = syr_rdtsc_overhead_mean / CALIB_LOOP_CNT; + +// printf("\nSYRTEM RDTSV realtime instrumentation calibration : cycles_diff_max %ld - tsc_duration_max %f us\n ", cycles_diff_max, tsc_duration_max); + + + + /* ************************************************************* + SYRTEM Clock_gettime MONOTONIC instrumentation overhead + */ + printf("\nCalibrating SYRTEM clock_gettime Realtime Instrumentation\n"); + calib_loop_count = CALIB_LOOP_CNT; + syr_clock_gettime_overhead_min = 1000; + syr_clock_gettime_overhead_max = 0; + syr_clock_gettime_overhead_mean = 0; + syr_clock_gettime_overhead_histogram = histogram_init( syr_clock_gettime_overhead_histogram ); + while(calib_loop_count) + { + + clock_gettime( CLOCK_MONOTONIC, &start ); + +// asm volatile(""); // Nop instruction + usleep(CALIB_USLEEP); + + clock_gettime( CLOCK_MONOTONIC, &stop ); + syr_clock_gettime_overhead_cur = TIMESPEC_TO_DOUBLE_US( get_timespec_diff( &start, &stop ) ); + + syr_clock_gettime_overhead_mean += syr_clock_gettime_overhead_cur; + if ( syr_clock_gettime_overhead_max < syr_clock_gettime_overhead_cur ) + syr_clock_gettime_overhead_max = syr_clock_gettime_overhead_cur; + if ( syr_clock_gettime_overhead_min > syr_clock_gettime_overhead_cur ) + syr_clock_gettime_overhead_min = syr_clock_gettime_overhead_cur; + histogram_store_value( syr_clock_gettime_overhead_histogram, (double)syr_clock_gettime_overhead_cur ); + + if ( calib_loop_count%CALIB_LOOP_REPORT_PERIOD == 0 ) + { + printf("\r%d/%d",calib_loop_count,CALIB_LOOP_CNT); + fflush(stdout); + } + + calib_loop_count--; + } + syr_clock_gettime_overhead_mean = syr_clock_gettime_overhead_mean / CALIB_LOOP_CNT; + +// printf("\nSYRTEM clock_gettime MONOTONIC calibration : clock_gettime duration_max %f us\n ", max); + + + printf("\n"); + + printf("OAI LT RT profiling overhead (it. %d) (us) : max=%8ld - mean=%8ld - min=%8ld\n", + CALIB_LOOP_CNT, + lt_overhead_max, lt_overhead_mean, lt_overhead_min); + printf("OAI SYR RT profiling overhead (it. %d) (us) : max=%8ld - mean=%8ld - min=%8ld\n", + CALIB_LOOP_CNT, + lt_syr_overhead_max, lt_syr_overhead_mean, lt_syr_overhead_min); + printf("SYR RDTSC profiling overhead (it. %d) (us) : max=%8.3f - mean=%8.3f - min=%8.3f\n", + CALIB_LOOP_CNT, + syr_rdtsc_overhead_max, syr_rdtsc_overhead_mean, syr_rdtsc_overhead_min); + printf("SYR clock_gettime profiling overhead (it. %d) (us): max=%8.3f - mean=%8.3f - min=%8.3f\n", + CALIB_LOOP_CNT, + syr_clock_gettime_overhead_max, syr_clock_gettime_overhead_mean, syr_clock_gettime_overhead_min); + + return 0; +#endif + + rxtx_proc = calloc( RX_NB_TH, sizeof( UE_rxtx_proc_t* ) ); + for (i=0 ; i<RX_NB_TH; i++) + rxtx_proc[i] = calloc( 1, sizeof( UE_rxtx_proc_t ) ); + + + th_wake_histogram = histogram_init( th_wake_histogram ); + + init_UE( 1 ); + + while ( !oai_exit ) + sleep( 1 ); + + return 0; +} + + +double estimate_MHz_syr(void) +{ + //copied blantantly from http://www.cs.helsinki.fi/linux/linux-kernel/2001-37/0256.html + /* + * $Id: MHz.c,v 1.4 2001/05/21 18:58:01 davej Exp $ + * This file is part of x86info. + * (C) 2001 Dave Jones. + * + * Licensed under the terms of the GNU GPL License version 2. + * + * Estimate CPU MHz routine by Andrea Arcangeli <andrea@suse.de> + * Small changes by David Sterba <sterd9am@ss1000.ms.mff.cuni.cz> + * + */ + + struct timespec start; + struct timespec stop; + + unsigned long long int cycles[2]; /* must be 64 bit */ + double microseconds; /* total time taken */ + + + /* get this function in cached memory */ + cycles[0] = rdtsc (); + clock_gettime( CLOCK_REALTIME, &start ); + + /* we don't trust that this is any specific length of time */ + usleep (100000); + + cycles[1] = rdtsc (); + clock_gettime( CLOCK_REALTIME, &stop ); + microseconds = TIMESPEC_TO_DOUBLE_US( get_timespec_diff( &start, &stop ) ); + + unsigned long long int elapsed = 0; + if (cycles[1] < cycles[0]) + { + //printf("c0 = %llu c1 = %llu",cycles[0],cycles[1]); + elapsed = UINT32_MAX - cycles[0]; + elapsed = elapsed + cycles[1]; + //printf("c0 = %llu c1 = %llu max = %llu elapsed=%llu\n",cycles[0], cycles[1], UINT32_MAX,elapsed); + } + else + { + elapsed = cycles[1] - cycles[0]; + // printf("\nc0 = %llu c1 = %llu elapsed=%llu\n",cycles[0], cycles[1],elapsed); + } + + double mhz = elapsed / microseconds; + + + //printf("%llg MHz processor (estimate). diff cycles=%llu microseconds=%llu \n", mhz, elapsed, microseconds); + //printf("%g elapsed %llu microseconds %llu\n",mhz, elapsed, microseconds); + return (mhz); +} + + + +/** TSC Timestamp references + + - http://oliveryang.net/2015/09/pitfalls-of-TSC-usage/#312-tsc-sync-behaviors-on-smp-system + - https://www.intel.com/content/www/us/en/embedded/training/ia-32-ia-64-benchmark-code-execution-paper.html + - https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-vol-3b-part-2-manual.pdf + + - http://blog.tinola.com/?e=54 + - https://stackoverflow.com/questions/24392392/getting-tsc-frequency-from-proc-cpuinfo !! warning on turbo + - https://gist.github.com/nfarring/1624742 + - https://www.lmax.com/blog/staff-blogs/2015/10/25/time-stamp-counters/ + - https://github.com/cyring/CoreFreq + - https://patchwork.kernel.org/patch/9438133/ --> TSC_ADJUST - to be checked + -> https://software.intel.com/en-us/forums/software-tuning-performance-optimization-platform-monitoring/topic/388964 + - https://www.google.fr/url?sa=t&rct=j&q=&esrc=s&source=web&cd=11&ved=0ahUKEwjwpJbem5DVAhWBDpoKHXv0Dt04ChAWCCIwAA&url=https%3A%2F%2Fsigarra.up.pt%2Ffeup%2Fpt%2Fpub_geral.show_file%3Fpi_gdoc_id%3D809041&usg=AFQjCNFHTMjmjWMG6QSVnLDflEoU0RavKw&cad=rja + - https://unix4lyfe.org/benchmarking/ + - https://stackoverflow.com/questions/27693145/rdtscp-versus-rdtsc-cpuid + - https://github.com/dterei/tsc/blob/master/tsc.h + - https://software.intel.com/en-us/forums/intel-isa-extensions/topic/280440 + - https://stackoverflow.com/questions/19941588/wrong-clock-cycle-measurements-with-rdtsc + + + +*/ + + + + + + +static __inline__ uint64_t pickCyclesStart(void) { + unsigned cycles_low, cycles_high; + asm volatile( "CPUID\n\t" // serialize + "RDTSC\n\t" // read clock + "MOV %%edx, %0\n\t" + "MOV %%eax, %1\n\t" + : "=r" (cycles_high), "=r" (cycles_low) + :: "%rax", "%rbx", "%rcx", "%rdx" ); +return ((uint64_t) cycles_high << 32) | cycles_low; +} + +static __inline__ uint64_t pickCyclesStop(void) { + uint32_t eax, edx; + + __asm__ __volatile__("rdtscp" + : "=a" (eax), "=d" (edx) + : + : "%ecx", "memory"); + +return (((uint64_t)edx << 32) | eax); +} + + + + + + + + +/************************************************************************************** + EXTRACT from openair1/PHY/TOOLS/time_meas.c +***************************************************************************************/ +double get_cpu_freq_GHz(void) { + + time_stats_t ts = {0}; + reset_meas(&ts); + ts.trials++; + ts.in = rdtsc_oai(); + sleep(1); + ts.diff = (rdtsc_oai()-ts.in); + cpu_freq_GHz = (double)ts.diff/1000000000; + printf("CPU Freq is %f \n", cpu_freq_GHz); + return cpu_freq_GHz; +} + + + +/************************************************************************************** + SYRTEM STATISTICS HELPER +***************************************************************************************/ + + + +histo_time_t *histogram_init(histo_time_t *histo ) +{ + int i = 0; + double max_val = HISTOGRAM_MIN_VALUE + HISTOGRAM_STEP; + + histo = calloc( HISTOGRAM_SIZE, sizeof( histo_time_t ) ); + if ( histo == NULL ) { + printf( "ERROR allocating histogram structure !\n" ); + return NULL; + } + + for ( i = 0; i < HISTOGRAM_SIZE; i++ ) { + histo[i].max = max_val; + max_val += HISTOGRAM_STEP; + } + + return histo; +} + + +void histogram_store_value( histo_time_t *histo, double value ) +{ + int i = 0; + + for ( i = 0; i < HISTOGRAM_SIZE; i++ ) { + if ( histo[i].max >= value || ( i + 1 ) == HISTOGRAM_SIZE ) { + histo[i].count++; + break; + } + } +} + + +void histogram_save_in_csv( histo_time_t *histo , char *file_sufix) +{ + char *csv_filename; + char month[3], day[3], hour[3], min[3], sec[3]; + time_t curr_time; + struct tm *datetime; + + curr_time = time( NULL ); + datetime = localtime( &curr_time ); + + csv_filename = calloc( sizeof( char ), 64 ); + if ( csv_filename == NULL ) { + return; + } + + memset( csv_filename, 0x00, 64 ); + memset( month, 0x00, 3 ); + memset( day, 0x00, 3 ); + memset( hour, 0x00, 3 ); + memset( min, 0x00, 3 ); + memset( sec, 0x00, 3 ); + +/* Month. */ + if ( datetime->tm_mon < 9 ) + snprintf( month, 3, "0%d", datetime->tm_mon + 1 ); + else + snprintf( month, 3, "%d", datetime->tm_mon + 1 ); + +/* Day. */ + if ( datetime->tm_mday < 10 ) + snprintf( day, 3, "0%d", datetime->tm_mday ); + else + snprintf( day, 3, "%d", datetime->tm_mday ); + +/* Hour. */ + if ( datetime->tm_hour < 10 ) + snprintf( hour, 3, "0%d", datetime->tm_hour ); + else + snprintf( hour, 3, "%d", datetime->tm_hour ); + +/* Minute. */ + if ( datetime->tm_min < 10 ) + snprintf( min, 3, "0%d", datetime->tm_min ); + else + snprintf( min, 3, "%d", datetime->tm_min ); + +/* Second. */ + if ( datetime->tm_sec < 10 ) + snprintf( sec, 3, "0%d", datetime->tm_sec ); + else + snprintf( sec, 3, "%d", datetime->tm_sec ); + + snprintf( csv_filename, 63, "ADRV9371_ZC706_HISTO_UEtoRXTX_%d%s%s%s%s%s_%s.csv", + datetime->tm_year + 1900, month, day, hour, min, sec, file_sufix ); + + FILE *fp; + int i = 0; + int min_val = 0; + + fp = fopen( csv_filename, "w+" ); + + fprintf( fp, "range;count\n" ); + + for ( i = 0; i < HISTOGRAM_SIZE; i++ ) { + if ( i + 1 == HISTOGRAM_SIZE ) + fprintf( fp, "%u+;%u\n", min_val, histo[i].count ); + else + fprintf( fp, "%u-%.0f;%u\n", min_val, histo[i].max, histo[i].count ); + min_val = histo[i].max; + } + + fclose( fp ); +} + + + +static struct timespec get_timespec_diff( + struct timespec *start, + struct timespec *stop ) +{ + struct timespec result; + + if ( ( stop->tv_nsec - start->tv_nsec ) < 0 ) { + result.tv_sec = stop->tv_sec - start->tv_sec - 1; + result.tv_nsec = stop->tv_nsec - start->tv_nsec + 1000000000; + } + else { + result.tv_sec = stop->tv_sec - start->tv_sec; + result.tv_nsec = stop->tv_nsec - start->tv_nsec; + } + + return result; +} + + +static void measure_time ( + struct timespec *start, + struct timespec *stop, + uint8_t START, + uint16_t PRINT_INTERVAL ) +{ + static double max = 0; + static double min = 0; + static double total = 0; + static int count = 0; + + if ( START ) { + clock_gettime( CLOCK_REALTIME, start ); + } + else { + clock_gettime( CLOCK_REALTIME, stop ); + + struct timespec diff; + double current = 0; + + diff = get_timespec_diff( start, stop ); +// current = ( (double)diff.tv_sec * 1000000 ) + ( (double)diff.tv_nsec / 1000 ); + current = TIMESPEC_TO_DOUBLE_US( diff ); + + if ( current > max ) { + max = current; + } + if ( min == 0 || current < min ) { + min = current; + } + total += current; + + histogram_store_value( th_wake_histogram, current ); + + if ( count % PRINT_INTERVAL == 0 && count != 0 ) { + double avg = total / ( count + 1 ); + printf( "[%d] Current : %.2lf µs, Min : %.2lf µs, Max : %.2lf µs, Moy : %.2lf µs\n", + count, current, min, max, avg ); + } + count++; + } +} + + + + + + + + + + + + + + + + diff --git a/targets/SIMU/USER/oaisim_functions.c b/targets/SIMU/USER/oaisim_functions.c index ceaae1958b9c08df2b57028dd7f54c4fa7fe79b5..c6907e666bc66e9d45bfe4e66d3036a0f9e2610c 100644 --- a/targets/SIMU/USER/oaisim_functions.c +++ b/targets/SIMU/USER/oaisim_functions.c @@ -1704,7 +1704,7 @@ void update_otg_eNB(module_id_t enb_module_idP, unsigned int ctime) } #else -#if 0 // defined(EXMIMO) || defined(OAI_USRP) +#if 0 // defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_ADRV9371_ZC706) if (otg_enabled==1) { ctime = frame * 100; diff --git a/targets/build_oai.bash b/targets/build_oai.bash index cfe5e35d2662b72c2e0d3dda473c121fee589c33..05b14a541b10a14dc6c4dfc72a939cbb1f37b8c0 100755 --- a/targets/build_oai.bash +++ b/targets/build_oai.bash @@ -344,6 +344,10 @@ build_enb(){ SOFTMODEM_DIRECTIVES="$SOFTMODEM_DIRECTIVES USRP=1 " fi + if [ $HW = "ADRV9371_ZC706" ]; then + SOFTMODEM_DIRECTIVES="$SOFTMODEM_DIRECTIVES ADRV9371_ZC706=1 " + fi + if [ $HW = "EXMIMO" ]; then SOFTMODEM_DIRECTIVES="$SOFTMODEM_DIRECTIVES EXMIMO=1 " fi