diff --git a/common/utils/LOG/log.h b/common/utils/LOG/log.h index 0004525d3c..93d8218466 100644 --- a/common/utils/LOG/log.h +++ b/common/utils/LOG/log.h @@ -161,16 +161,12 @@ extern "C" { {NULL,-1}\ } - - #define SET_LOG_DEBUG(B) g_log->debug_mask = (g_log->debug_mask | B) #define CLEAR_LOG_DEBUG(B) g_log->debug_mask = (g_log->debug_mask & (~B)) #define SET_LOG_DUMP(B) g_log->dump_mask = (g_log->dump_mask | B) #define CLEAR_LOG_DUMP(B) g_log->dump_mask = (g_log->dump_mask & (~B)) - - typedef enum { MIN_LOG_COMPONENTS = 0, PHY = MIN_LOG_COMPONENTS, @@ -233,7 +229,6 @@ comp_name_t; #define MAX_LOG_DYNALLOC_COMPONENTS 20 #define MAX_LOG_COMPONENTS (MAX_LOG_PREDEF_COMPONENTS + MAX_LOG_DYNALLOC_COMPONENTS) - typedef struct { char *name; /*!< \brief string name of item */ int value; /*!< \brief integer value of mapping */ @@ -265,8 +260,6 @@ typedef struct { uint64_t dump_mask; } log_t; - - #ifdef LOG_MAIN log_t *g_log; #else @@ -365,9 +358,6 @@ int32_t write_file_matlab(const char *fname, const char *vname, void *data, int " level: add log level indication in log messages\n"\ " thread: add threads names in log messages\n" - - - /*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ /* LOG global configuration parameters */ /* optname help paramflags XXXptr defXXXval type numelt */ @@ -396,41 +386,166 @@ int32_t write_file_matlab(const char *fname, const char *vname, void *data, int # if T_TRACER #include "T.h" /* per component, level dependent macros */ -# define LOG_E(c, x...) do { T(T_LEGACY_ ## c ## _ERROR, T_PRINTF(x)) ; if (T_stdout) { if( g_log->log_component[c].level >= OAILOG_ERR ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_ERR, x) ;} } while (0) -# define LOG_W(c, x...) do { T(T_LEGACY_ ## c ## _WARNING, T_PRINTF(x)); if (T_stdout) { if( g_log->log_component[c].level >= OAILOG_WARNING ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_WARNING, x) ;} } while (0) -# define LOG_A(c, x...) do { T(T_LEGACY_ ## c ## _INFO, T_PRINTF(x)) ; if (T_stdout) { if( g_log->log_component[c].level >= OAILOG_ANALYSIS) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_ANALYSIS, x);} } while (0) -# define LOG_I(c, x...) do { T(T_LEGACY_ ## c ## _INFO, T_PRINTF(x)) ; if (T_stdout) { if( g_log->log_component[c].level >= OAILOG_INFO ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_INFO, x) ;} } while (0) -# define LOG_D(c, x...) do { T(T_LEGACY_ ## c ## _DEBUG, T_PRINTF(x)) ; if (T_stdout) { if( g_log->log_component[c].level >= OAILOG_DEBUG ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_DEBUG, x) ;} } while (0) -# define LOG_T(c, x...) do { T(T_LEGACY_ ## c ## _TRACE, T_PRINTF(x)) ; if (T_stdout) { if( g_log->log_component[c].level >= OAILOG_TRACE ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_TRACE, x) ;} } while (0) -# define VLOG(c,l, f, args) do { if (T_stdout) { if( g_log->log_component[c].level >= l ) vlogRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, l, f, args) ;} } while (0) +#define LOG_E(c, x...) \ + do { \ + T(T_LEGACY_##c##_ERROR, T_PRINTF(x)); \ + if (T_stdout) { \ + if (g_log->log_component[c].level >= OAILOG_ERR) \ + logRecord_mt(__FILE__, __FUNCTION__, __LINE__, c, OAILOG_ERR, x); \ + } \ + } while (0) + +#define LOG_W(c, x...) \ + do { \ + T(T_LEGACY_##c##_WARNING, T_PRINTF(x)); \ + if (T_stdout) { \ + if (g_log->log_component[c].level >= OAILOG_WARNING) \ + logRecord_mt(__FILE__, __FUNCTION__, __LINE__, c, OAILOG_WARNING, x); \ + } \ + } while (0) + +#define LOG_A(c, x...) \ + do { \ + T(T_LEGACY_##c##_INFO, T_PRINTF(x)); \ + if (T_stdout) { \ + if (g_log->log_component[c].level >= OAILOG_ANALYSIS) \ + logRecord_mt(__FILE__, __FUNCTION__, __LINE__, c, OAILOG_ANALYSIS, x); \ + } \ + } while (0) + +#define LOG_I(c, x...) \ + do { \ + T(T_LEGACY_##c##_INFO, T_PRINTF(x)); \ + if (T_stdout) { \ + if (g_log->log_component[c].level >= OAILOG_INFO) \ + logRecord_mt(__FILE__, __FUNCTION__, __LINE__, c, OAILOG_INFO, x); \ + } \ + } while (0) + +#define LOG_D(c, x...) \ + do { \ + T(T_LEGACY_##c##_DEBUG, T_PRINTF(x)); \ + if (T_stdout) { \ + if (g_log->log_component[c].level >= OAILOG_DEBUG) \ + logRecord_mt(__FILE__, __FUNCTION__, __LINE__, c, OAILOG_DEBUG, x); \ + } \ + } while (0) + +#define LOG_DDUMP(c, b, s, f, x...) \ + do { \ + T(T_LEGACY_##c##_DEBUG, T_PRINTF(x)); \ + if (T_stdout) { \ + if (g_log->log_component[c].level >= OAILOG_DEBUG) \ + log_dump(c, b, s, f, x); \ + } \ + } while (0) + +#define LOG_T(c, x...) \ + do { \ + T(T_LEGACY_##c##_TRACE, T_PRINTF(x)); \ + if (T_stdout) { \ + if (g_log->log_component[c].level >= OAILOG_TRACE) \ + logRecord_mt(__FILE__, __FUNCTION__, __LINE__, c, OAILOG_TRACE, x); \ + } \ + } while (0) + +#define VLOG(c, l, f, args) \ + do { \ + if (T_stdout) { \ + if (g_log->log_component[c].level >= l) \ + vlogRecord_mt(__FILE__, __FUNCTION__, __LINE__, c, l, f, args); \ + } \ + } while (0) + /* macro used to dump a buffer or a message as in openair2/RRC/LTE/RRC_eNB.c, replaces LOG_F macro */ -# define LOG_DUMPMSG(c, f, b, s, x...) do { if(g_log->dump_mask & f) log_dump(c, b, s, LOG_DUMP_CHAR, x) ;} while (0) /* */ +#define LOG_DUMPMSG(c, f, b, s, x...) \ + do { \ + if (g_log->dump_mask & f) \ + log_dump(c, b, s, LOG_DUMP_CHAR, x); \ + } while (0) + /* bitmask dependent macros, to isolate debugging code */ -# define LOG_DEBUGFLAG(D) (g_log->debug_mask & D) +#define LOG_DEBUGFLAG(D) (g_log->debug_mask & D) /* bitmask dependent macros, to generate debug file such as matlab file or message dump */ -# define LOG_DUMPFLAG(D) (g_log->dump_mask & D) -# define LOG_M(file, vector, data, len, dec, format) do { write_file_matlab(file, vector, data, len, dec, format, 0);} while(0)/* */ +#define LOG_DUMPFLAG(D) (g_log->dump_mask & D) + +#define LOG_M(file, vector, data, len, dec, format) \ + do { \ + write_file_matlab(file, vector, data, len, dec, format, 0); \ + } while (0) + /* define variable only used in LOG macro's */ -# define LOG_VAR(A,B) A B -# else /* T_TRACER */ -# define LOG_E(c, x...) do { if( g_log->log_component[c].level >= OAILOG_ERR ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_ERR, x) ;} while (0) -# define LOG_W(c, x...) do { if( g_log->log_component[c].level >= OAILOG_WARNING ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_WARNING, x) ;} while (0) -# define LOG_A(c, x...) do { if( g_log->log_component[c].level >= OAILOG_ANALYSIS) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_ANALYSIS, x);} while (0) -# define LOG_I(c, x...) do { if( g_log->log_component[c].level >= OAILOG_INFO ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_INFO, x) ;} while (0) -# define LOG_D(c, x...) do { if( g_log->log_component[c].level >= OAILOG_DEBUG ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_DEBUG, x) ;} while (0) -# define LOG_T(c, x...) do { if( g_log->log_component[c].level >= OAILOG_TRACE ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_TRACE, x) ;} while (0) -# define VLOG(c,l, f, args) do { if( g_log->log_component[c].level >= l ) vlogRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, l, f, args) ; } while (0) +#define LOG_VAR(A, B) A B -# define nfapi_log(FILE, FNC, LN, COMP, LVL, FMT...) -# define LOG_DEBUGFLAG(D) (g_log->dump_mask & D) -# define LOG_DUMPFLAG(D) (g_log->debug_mask & D) -# define LOG_DUMPMSG(c, f, b, s, x...) do { if(g_log->dump_mask & f) log_dump(c, b, s, LOG_DUMP_CHAR, x) ;} while (0) /* */ +#else /* no T_TRACER */ -# define LOG_M(file, vector, data, len, dec, format) do { write_file_matlab(file, vector, data, len, dec, format, 0);} while(0) -# define LOG_VAR(A,B) A B -# define T_ACTIVE(a) (0) -# endif /* T_TRACER */ +#define LOG_E(c, x...) \ + do { \ + if (g_log->log_component[c].level >= OAILOG_ERR) \ + logRecord_mt(__FILE__, __FUNCTION__, __LINE__, c, OAILOG_ERR, x); \ + } while (0) + +#define LOG_W(c, x...) \ + do { \ + if (g_log->log_component[c].level >= OAILOG_WARNING) \ + logRecord_mt(__FILE__, __FUNCTION__, __LINE__, c, OAILOG_WARNING, x); \ + } while (0) + +#define LOG_A(c, x...) \ + do { \ + if (g_log->log_component[c].level >= OAILOG_ANALYSIS) \ + logRecord_mt(__FILE__, __FUNCTION__, __LINE__, c, OAILOG_ANALYSIS, x); \ + } while (0) + +#define LOG_I(c, x...) \ + do { \ + if (g_log->log_component[c].level >= OAILOG_INFO) \ + logRecord_mt(__FILE__, __FUNCTION__, __LINE__, c, OAILOG_INFO, x); \ + } while (0) + +#define LOG_D(c, x...) \ + do { \ + if (g_log->log_component[c].level >= OAILOG_DEBUG) \ + logRecord_mt(__FILE__, __FUNCTION__, __LINE__, c, OAILOG_DEBUG, x); \ + } while (0) + +#define LOG_DDUMP(c, b, s, f, x...) \ + do { \ + if (g_log->log_component[c].level >= OAILOG_DEBUG) \ + log_dump(c, b, s, f, x); \ + } while (0) + +#define LOG_T(c, x...) \ + do { \ + if (g_log->log_component[c].level >= OAILOG_TRACE) \ + logRecord_mt(__FILE__, __FUNCTION__, __LINE__, c, OAILOG_TRACE, x); \ + } while (0) + +#define VLOG(c, l, f, args) \ + do { \ + if (g_log->log_component[c].level >= l) \ + vlogRecord_mt(__FILE__, __FUNCTION__, __LINE__, c, l, f, args); \ + } while (0) + +#define nfapi_log(FILE, FNC, LN, COMP, LVL, FMT...) +#define LOG_DEBUGFLAG(D) (g_log->dump_mask & D) +#define LOG_DUMPFLAG(D) (g_log->debug_mask & D) +#define LOG_DUMPMSG(c, f, b, s, x...) \ + do { \ + if (g_log->dump_mask & f) \ + log_dump(c, b, s, LOG_DUMP_CHAR, x); \ + } while (0) /* */ + +#define LOG_M(file, vector, data, len, dec, format) \ + do { \ + write_file_matlab(file, vector, data, len, dec, format, 0); \ + } while (0) + +#define LOG_VAR(A, B) A B +#define T_ACTIVE(a) (0) + +#endif /* T_TRACER */ /* avoid warnings for variables only used in LOG macro's but set outside debug section */ #define GCC_NOTUSED __attribute__((unused)) diff --git a/executables/lte-enb.c b/executables/lte-enb.c index 516fafd336..532d8bcfc0 100644 --- a/executables/lte-enb.c +++ b/executables/lte-enb.c @@ -103,7 +103,6 @@ struct timing_info_t { } timing_info; // Fix per CC openair rf/if device update -// extern openair0_device openair0; extern int oai_exit; diff --git a/executables/lte-ru.c b/executables/lte-ru.c index b9db0348e3..2cee48ffbc 100644 --- a/executables/lte-ru.c +++ b/executables/lte-ru.c @@ -808,26 +808,31 @@ void tx_rf(RU_t *ru, /* add fail safe for late command end */ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 ); // prepare tx buffer pointers - txs = ru->rfdevice.trx_write_func(&ru->rfdevice, - timestamp+ru->ts_offset-ru->openair0_cfg.tx_sample_advance-sf_extension, - txp, - siglen+sf_extension, - ru->nb_tx, - flags); - ru->south_out_cnt++; - LOG_D(PHY,"south_out_cnt %d\n",ru->south_out_cnt); - int se = dB_fixed(signal_energy(txp[0],siglen+sf_extension)); + txs = ru->rfdevice + .trx_write_func(&ru->rfdevice, timestamp + ru->ts_offset - sf_extension, txp, siglen + sf_extension, ru->nb_tx, flags); + ru->south_out_cnt++; + LOG_D(PHY, "south_out_cnt %d\n", ru->south_out_cnt); + int se = dB_fixed(signal_energy(txp[0], siglen + sf_extension)); - if (SF_type == SF_S) LOG_D(PHY,"[TXPATH] RU %d tx_rf (en %d,len %d), writing to TS %llu, frame %d, unwrapped_frame %d, subframe %d\n",ru->idx, se, - siglen+sf_extension, (long long unsigned int)timestamp, frame, proc->frame_tx_unwrap, subframe); + if (SF_type == SF_S) + LOG_D(PHY, + "[TXPATH] RU %d tx_rf (en %d,len %d), writing to TS %llu, frame %d, unwrapped_frame %d, subframe %d\n", + ru->idx, + se, + siglen + sf_extension, + (long long unsigned int)timestamp, + frame, + proc->frame_tx_unwrap, + subframe); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 ); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0); - // AssertFatal(txs == siglen+sf_extension,"TX : Timeout (sent %d/%d)\n",txs, siglen); - if( usrp_tx_thread == 0 && (txs != siglen+sf_extension) && (late_control==STATE_BURST_NORMAL) ) { /* add fail safe for late command */ - late_control=STATE_BURST_TERMINATE; - LOG_E(PHY,"TX : Timeout (sent %d/%d) state =%d\n",txs, siglen,late_control); - } + // AssertFatal(txs == siglen+sf_extension,"TX : Timeout (sent %d/%d)\n",txs, siglen); + if (usrp_tx_thread == 0 && (txs != siglen + sf_extension) + && (late_control == STATE_BURST_NORMAL)) { /* add fail safe for late command */ + late_control = STATE_BURST_TERMINATE; + LOG_E(PHY, "TX : Timeout (sent %d/%d) state =%d\n", txs, siglen, late_control); + } } else if (IS_SOFTMODEM_RFSIM ) { // in case of rfsim, we always enable tx because we need to feed rx of the opposite side // we write 1 single I/Q sample to trigger Rx (rfsim will fill gaps with 0 I/Q) @@ -836,15 +841,15 @@ void tx_rf(RU_t *ru, memset(dummy_tx_data,0,sizeof(dummy_tx_data)); for (int i=0; iframe_parms->nb_antennas_tx; i++) dummy_tx[i]= dummy_tx_data[i]; - - AssertFatal( 1 == - ru->rfdevice.trx_write_func(&ru->rfdevice, - timestamp+ru->ts_offset-ru->openair0_cfg.tx_sample_advance-sf_extension, - dummy_tx, - 1, - ru->frame_parms->nb_antennas_tx, - 4),""); - + + AssertFatal(1 + == ru->rfdevice.trx_write_func(&ru->rfdevice, + timestamp + ru->ts_offset - sf_extension, + dummy_tx, + 1, + ru->frame_parms->nb_antennas_tx, + 4), + ""); } } diff --git a/executables/lte-softmodem.h b/executables/lte-softmodem.h index 4143bce3a4..ac403ecfec 100644 --- a/executables/lte-softmodem.h +++ b/executables/lte-softmodem.h @@ -74,15 +74,7 @@ #define CONFIG_HLP_DLSHIFT "dynamic shift for LLR compuation for TM3/4 (default 0)\n" #define CONFIG_HLP_USRP_ARGS "set the arguments to identify USRP (same syntax as in UHD)\n" #define CONFIG_HLP_DMAMAP "use DMA memory mapping\n" -#define CONFIG_HLP_TDD "Set hardware to TDD mode (default: FDD). Used only with -U (otherwise set in config file).\n" -#define CONFIG_HLP_TADV "Set timing_advance\n" - - - - - - - +#define CONFIG_HLP_TDD "Set hardware to TDD mode (default: FDD). Used only with -U (otherwise set in config file).\n" /*-------------------------------------------------------------------------------------------------------------------------------------------------------*/ /* command line parameters specific to UE */ @@ -106,7 +98,6 @@ {"usrp-args", CONFIG_HLP_USRP_ARGS, 0, .strptr=&usrp_args, .defstrval="type=b200",TYPE_STRING, 0}, \ {"mmapped-dma", CONFIG_HLP_DMAMAP, PARAMFLAG_BOOL, .uptr=&mmapped_dma, .defintval=0, TYPE_INT, 0}, \ {"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, .iptr=&tddflag, .defintval=0, TYPE_INT, 0}, \ - {"A", CONFIG_HLP_TADV, 0, .iptr=&(timingadv), .defintval=0, TYPE_INT, 0}, \ {"ue-idx-standalone", NULL, 0, .u16ptr=&ue_idx_standalone, .defuintval=0xFFFF, TYPE_UINT16, 0}, \ {"node-number", NULL, 0, .u16ptr=&node_number, .defuintval=2, TYPE_UINT16, 0}, \ } diff --git a/executables/lte-ue.c b/executables/lte-ue.c index 60ca068d64..5176533b8e 100644 --- a/executables/lte-ue.c +++ b/executables/lte-ue.c @@ -169,7 +169,6 @@ PHY_VARS_UE *init_ue_vars(LTE_DL_FRAME_PARMS *frame_parms, memcpy(&(ue->frame_parms), frame_parms, sizeof(LTE_DL_FRAME_PARMS)); } - ue->hw_timing_advance=get_softmodem_params()->hw_timing_advance; ue->Mod_id = UE_id; ue->mac_enabled = 1; @@ -1940,16 +1939,15 @@ void *UE_thread(void *arg) { rxp, readBlockSize, UE->frame_parms.nb_antennas_rx),""); - AssertFatal( writeBlockSize == - UE->rfdevice.trx_write_func(&UE->rfdevice, - timestamp+ - (2*UE->frame_parms.samples_per_tti) - - UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0 - - openair0_cfg[0].tx_sample_advance, - txp, - writeBlockSize, - UE->frame_parms.nb_antennas_tx, - 1),""); + AssertFatal(writeBlockSize + == UE->rfdevice.trx_write_func(&UE->rfdevice, + timestamp + (2 * UE->frame_parms.samples_per_tti) + - UE->frame_parms.ofdm_symbol_size - UE->frame_parms.nb_prefix_samples0, + txp, + writeBlockSize, + UE->frame_parms.nb_antennas_tx, + 1), + ""); if( sub_frame==9) { // read in first symbol of next frame and adjust for timing drift diff --git a/executables/lte-uesoftmodem.c b/executables/lte-uesoftmodem.c index 95dfdeddf4..e26e10d6ee 100644 --- a/executables/lte-uesoftmodem.c +++ b/executables/lte-uesoftmodem.c @@ -274,8 +274,7 @@ static void get_options(configmodule_interface_t *cfg) { int CC_id=0; int tddflag=0; - int dumpframe=0; - int timingadv=0; + int dumpframe = 0; uint8_t nfapi_mode = NFAPI_MONOLITHIC; set_default_frame_parms(frame_parms); @@ -289,8 +288,6 @@ static void get_options(configmodule_interface_t *cfg) config_process_cmdline(cfg, cmdline_ueparams, sizeofArray(cmdline_ueparams), NULL); nfapi_setmode(nfapi_mode); - get_softmodem_params()->hw_timing_advance = timingadv; - if ( (cmdline_uemodeparams[CMDLINE_CALIBUERX_IDX].paramflags & PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue; if ( (cmdline_uemodeparams[CMDLINE_CALIBUERXMED_IDX].paramflags & PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue_med; diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index c66123112f..2a12126d7d 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -90,12 +90,8 @@ #include #include -//#define USRP_DEBUG 1 -// Fix per CC openair rf/if device update -// extern openair0_device openair0; - - -//pthread_t main_gNB_thread; +// #define USRP_DEBUG 1 +// Fix per CC openair rf/if device update time_stats_t softmodem_stats_mt; // main thread time_stats_t softmodem_stats_hw; // hw acquisition diff --git a/executables/nr-ru.c b/executables/nr-ru.c index 3ccc7dacc6..92fdc57e00 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -102,7 +102,6 @@ int attach_rru(RU_t *ru); int connect_rau(RU_t *ru); static void NRRCconfig_RU(configmodule_interface_t *cfg); -extern uint32_t timing_advance; extern int emulate_rf; extern int numerology; @@ -857,22 +856,17 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) { for (i = 0; i < ru->nb_tx; i++) txp[i] = (void *)&ru->common.txdata[i][fp->get_samples_slot_timestamp(slot, fp, 0)] - sf_extension * sizeof(int32_t); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, - (timestamp + ru->ts_offset - ru->openair0_cfg.tx_sample_advance - timing_advance) & 0xffffffff); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (timestamp + ru->ts_offset) & 0xffffffff); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1); // prepare tx buffer pointers - txs = ru->rfdevice.trx_write_func(&ru->rfdevice, - timestamp + ru->ts_offset - ru->openair0_cfg.tx_sample_advance - timing_advance - sf_extension, - txp, - siglen + sf_extension, - ru->nb_tx, - flags); + txs = ru->rfdevice + .trx_write_func(&ru->rfdevice, timestamp + ru->ts_offset - sf_extension, txp, siglen + sf_extension, ru->nb_tx, flags); LOG_D(PHY, "[TXPATH] RU %d aa %d tx_rf, writing to TS %llu, %d.%d, unwrapped_frame %d, slot %d, flags %d, siglen+sf_extension %d, " "returned %d, E %f\n", ru->idx, i, - (long long unsigned int)(timestamp + ru->ts_offset - ru->openair0_cfg.tx_sample_advance - timing_advance - sf_extension), + (long long unsigned int)(timestamp + ru->ts_offset - sf_extension), frame, slot, proc->frame_tx_unwrap, diff --git a/executables/nr-softmodem-common.h b/executables/nr-softmodem-common.h index 19760bdd26..46763d6995 100644 --- a/executables/nr-softmodem-common.h +++ b/executables/nr-softmodem-common.h @@ -56,8 +56,7 @@ #define CONFIG_HLP_DMAMAP "use DMA memory mapping\n" #define CONFIG_HLP_EXCCLK "tells hardware to use a clock reference (0:internal(default), 1:external, 2:gpsdo)\n" #define CONFIG_HLP_USIM "use XOR autentication algo in case of test usim mode\n" -#define CONFIG_HLP_NOSNGLT "Disables single-thread mode in lte-softmodem\n" -#define CONFIG_HLP_TADV "Set timing_advance\n" +#define CONFIG_HLP_NOSNGLT "Disables single-thread mode in lte-softmodem\n" #define CONFIG_HLP_DLF "Set the downlink frequency for all component carriers\n" #define CONFIG_HLP_ULOFF "Set the uplink frequnecy offset for all component carriers\n" #define CONFIG_HLP_CHOFF "Channel id offset\n" @@ -80,8 +79,7 @@ #define CONFIG_HLP_L2MONW "Enable L2 wireshark messages on localhost \n" #define CONFIG_HLP_L2MONP "Enable L2 pcap messages on localhost \n" #define CONFIG_HLP_MAC "Disable the MAC procedures at UE side (default is enabled)\n" -#define CONFIG_HLP_VCD "Enable VCD (generated file will is named openair_dump_eNB.vcd, read it with target/RT/USER/eNB.gtkw\n" -#define CONFIG_HLP_TQFS "Apply three-quarter of sampling frequency, 23.04 Msps to reduce the data rate on USB/PCIe transfers (only valid for 20 MHz)\n" +#define CONFIG_HLP_VCD "Enable VCD (generated file will is named openair_dump_eNB.vcd, read it with target/RT/USER/eNB.gtkw\n" #define CONFIG_HLP_TPORT "tracer port\n" #define CONFIG_HLP_NOTWAIT "don't wait for tracer, start immediately\n" #define CONFIG_HLP_TNOFORK "to ease debugging with gdb\n" @@ -109,6 +107,7 @@ #define CONFIG_HLP_SNR "Set average SNR in dB (for --siml1 option)\n" #define CONFIG_HLP_NOS1 "Disable s1 interface\n" #define CONFIG_HLP_NOKRNMOD "(noS1 only): Use tun instead of namesh module \n" + /*--------------------------------------------------------------------------------------------------------------------------------*/ /* command line parameters for LOG utility */ /* optname helpstr paramflags XXXptr defXXXval type numelt */ diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index 6192dacb86..ee6ad7200e 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -108,8 +108,6 @@ static int wait_for_sync = 0; unsigned int mmapped_dma=0; int single_thread_flag=1; -int8_t threequarter_fs=0; - uint64_t downlink_frequency[MAX_NUM_CCs][4]; int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; @@ -145,12 +143,6 @@ int rx_input_level_dBm; int otg_enabled; -//int number_of_cards = 1; - - -//static NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]; -//static nfapi_nr_config_request_t *config[MAX_NUM_CCs]; -uint32_t timing_advance = 0; uint64_t num_missed_slots=0; // counter for the number of missed slots #include @@ -171,8 +163,6 @@ static char *worker_config = NULL; /* struct for ethernet specific parameters given in eNB conf file */ eth_params_t *eth_params; -openair0_config_t openair0_cfg[MAX_CARDS]; - double cpuf; /* hack: pdcp_run() is required by 4G scheduler which is compiled into @@ -633,7 +623,6 @@ int main( int argc, char **argv ) { setvbuf(stderr, NULL, _IONBF, 0); #endif mode = normal_txrx; - memset(&openair0_cfg[0],0,sizeof(openair0_config_t)*MAX_CARDS); memset(tx_max_power,0,sizeof(int)*MAX_NUM_CCs); logInit(); set_latency_target(); @@ -647,8 +636,6 @@ int main( int argc, char **argv ) { exit(-1); } - openair0_cfg[0].threequarter_fs = threequarter_fs; - if (get_softmodem_params()->do_ra) AssertFatal(get_softmodem_params()->phy_test == 0,"RA and phy_test are mutually exclusive\n"); diff --git a/executables/nr-softmodem.h b/executables/nr-softmodem.h index cc76e9e375..54bcc0fc5d 100644 --- a/executables/nr-softmodem.h +++ b/executables/nr-softmodem.h @@ -18,8 +18,6 @@ // clang-format off #define CMDLINE_PARAMS_DESC_GNB { \ {"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, .iptr=&single_thread_flag, .defintval=1, TYPE_INT, 0}, \ - {"A" , CONFIG_HLP_TADV, 0, .uptr=&timing_advance, .defintval=0, TYPE_UINT, 0}, \ - {"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, .i8ptr=&threequarter_fs, .defintval=0, TYPE_INT8, 0}, \ {"m" , CONFIG_HLP_DLMCS_PHYTEST, 0, .uptr=&target_dl_mcs, .defintval=0, TYPE_UINT, 0}, \ {"l" , CONFIG_HLP_DLNL_PHYTEST, 0, .uptr=&target_dl_Nl, .defintval=0, TYPE_UINT, 0}, \ {"L" , CONFIG_HLP_ULNL_PHYTEST, 0, .uptr=&target_ul_Nl, .defintval=0, TYPE_UINT, 0}, \ diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 1ceb49e0d7..98c0443422 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -933,8 +933,7 @@ void *UE_thread(void *arg) // use previous timing_advance value to compute writeTimestamp writeTimestamp = timestamp + UE->frame_parms.get_samples_slot_timestamp(slot_nr,&UE->frame_parms,DURATION_RX_TO_TX) - - firstSymSamp - openair0_cfg[0].tx_sample_advance - - UE->N_TA_offset - timing_advance; + - firstSymSamp - UE->N_TA_offset - timing_advance; // but use current UE->timing_advance value to compute writeBlockSize if (UE->timing_advance != timing_advance) { diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 24e5b53629..de1c97a07b 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -293,7 +293,6 @@ void set_options(int CC_id, PHY_VARS_NR_UE *UE){ UE->chest_freq = nrUE_params.chest_freq; UE->chest_time = nrUE_params.chest_time; UE->no_timing_correction = nrUE_params.no_timing_correction; - UE->timing_advance = nrUE_params.timing_advance; LOG_I(PHY,"Set UE_fo_compensation %d, UE_scan_carrier %d, UE_no_timing_correction %d \n, chest-freq %d, chest-time %d\n", UE->UE_fo_compensation, UE->UE_scan_carrier, UE->no_timing_correction, UE->chest_freq, UE->chest_time); @@ -307,7 +306,7 @@ void set_options(int CC_id, PHY_VARS_NR_UE *UE){ fp->nb_antennas_rx = nrUE_params.nb_antennas_rx; fp->nb_antennas_tx = nrUE_params.nb_antennas_tx; - fp->threequarter_fs = nrUE_params.threequarter_fs; + fp->threequarter_fs = get_softmodem_params()->threequarter_fs; fp->N_RB_DL = nrUE_params.N_RB_DL; fp->ssb_start_subcarrier = nrUE_params.ssb_start_subcarrier; fp->ofdm_offset_divisor = nrUE_params.ofdm_offset_divisor; diff --git a/executables/nr-uesoftmodem.h b/executables/nr-uesoftmodem.h index 7adba3fa97..676a8a4e68 100644 --- a/executables/nr-uesoftmodem.h +++ b/executables/nr-uesoftmodem.h @@ -52,8 +52,6 @@ {"ue-scan-carrier", CONFIG_HLP_UESCAN, PARAMFLAG_BOOL, .iptr=&(nrUE_params.UE_scan_carrier), .defintval=0, TYPE_INT, 0}, \ {"ue-fo-compensation", CONFIG_HLP_UEFO, PARAMFLAG_BOOL, .iptr=&(nrUE_params.UE_fo_compensation), .defintval=0, TYPE_INT, 0}, \ {"ue-max-power", NULL, 0, .iptr=&(tx_max_power[0]), .defintval=90, TYPE_INT, 0}, \ - {"A" , CONFIG_HLP_TADV, 0, .iptr=&(nrUE_params.timing_advance), .defintval=0, TYPE_INT, 0}, \ - {"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, .iptr=&(nrUE_params.threequarter_fs), .defintval=0, TYPE_UINT8, 0}, \ {"r" , CONFIG_HLP_PRB_SA, 0, .iptr=&(nrUE_params.N_RB_DL), .defintval=106, TYPE_UINT, 0}, \ {"ssb", CONFIG_HLP_SSC, 0, .iptr=&(nrUE_params.ssb_start_subcarrier), .defintval=516, TYPE_UINT16, 0}, \ {"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, .iptr=&tddflag, .defintval=0, TYPE_INT, 0}, \ @@ -72,16 +70,14 @@ typedef struct { int max_ldpc_iterations; // number of maximum LDPC iterations tpool_t Tpool; // thread pool int UE_scan_carrier; - int UE_fo_compensation; - int timing_advance; + int UE_fo_compensation; uint64_t if_freq; int if_freq_off; int chest_freq; int chest_time; int no_timing_correction; int nb_antennas_rx; - int nb_antennas_tx; - int threequarter_fs; + int nb_antennas_tx; int N_RB_DL; int ssb_start_subcarrier; } nrUE_params_t; diff --git a/executables/softmodem-common.c b/executables/softmodem-common.c index 316a5b14c9..b750092a39 100644 --- a/executables/softmodem-common.c +++ b/executables/softmodem-common.c @@ -106,6 +106,7 @@ void get_common_options(configmodule_interface_t *cfg, uint32_t execmask) paramdef_t cmdline_params[] = CMDLINE_PARAMS_DESC; checkedparam_t cmdline_CheckParams[] = CMDLINE_PARAMS_CHECK_DESC; int numparams = sizeofArray(cmdline_params); + AssertFatal(numparams == sizeofArray(cmdline_CheckParams), "Error in arrays size (%d!=%lu)\n", numparams, sizeofArray(cmdline_CheckParams)); config_set_checkfunctions(cmdline_params, cmdline_CheckParams, numparams); config_get(cfg, cmdline_params, numparams, NULL); nfapi_index = config_paramidx_fromname(cmdline_params, numparams, "nfapi"); @@ -115,6 +116,8 @@ void get_common_options(configmodule_interface_t *cfg, uint32_t execmask) paramdef_t cmdline_logparams[] =CMDLINE_LOGPARAMS_DESC ; checkedparam_t cmdline_log_CheckParams[] = CMDLINE_LOGPARAMS_CHECK_DESC; int numlogparams = sizeofArray(cmdline_logparams); + AssertFatal(numlogparams == sizeofArray(cmdline_log_CheckParams), "Error in arrays size (%d!=%lu)\n", numlogparams, sizeofArray(cmdline_log_CheckParams)); + config_set_checkfunctions(cmdline_logparams, cmdline_log_CheckParams, numlogparams); config_get(cfg, cmdline_logparams, numlogparams, NULL); diff --git a/executables/softmodem-common.h b/executables/softmodem-common.h index 9dcc5c8e1b..50aa335efb 100644 --- a/executables/softmodem-common.h +++ b/executables/softmodem-common.h @@ -84,7 +84,9 @@ extern "C" #define CONFIG_HLP_ULMCS "Set the maximum uplink MCS\n" #define CONFIG_HLP_UE "Set the lte softmodem as a UE\n" -#define CONFIG_HLP_TQFS "Apply three-quarter of sampling frequency, 23.04 Msps to reduce the data rate on USB/PCIe transfers (only valid for 20 MHz)\n" +#define CONFIG_HLP_TQFS \ + "Apply three-quarter of sampling frequency, (example 23.04 Msps for LTE 20MHz) to reduce the data rate on USB/PCIe transfers " \ + "(only valid for some bandwidths)\n" #define CONFIG_HLP_TPORT "tracer port\n" #define CONFIG_HLP_NOTWAIT "don't wait for tracer, start immediately\n" #define CONFIG_HLP_TNOFORK "to ease debugging with gdb\n" @@ -108,6 +110,9 @@ extern "C" #define CONFIG_HLP_NOITTI "Do not start itti threads, call queue processing in place, inside the caller thread" #define CONFIG_HLP_LDPC_OFFLOAD "Enable LDPC offload to AMD Xilinx T2 telco card\n" #define CONFIG_HLP_SYNC_REF "UE acts a Sync Reference in Sidelink. 0-none 1-GNB 2-GNSS 4-localtiming\n" +#define CONFIG_HLP_TADV \ + "Set RF board timing_advance to compensate fix delay inside the RF board between Rx and Tx timestamps (RF board internal " \ + "issues)\n" /*-----------------------------------------------------------------------------------------------------------------------------------------------------*/ /* command line parameters common to eNodeB and UE */ @@ -187,6 +192,8 @@ extern int usrp_tx_thread; {"no-itti-threads", CONFIG_HLP_NOITTI, PARAMFLAG_BOOL, .iptr=&softmodem_params.no_itti, .defintval=0, TYPE_INT, 0}, \ {"ldpc-offload-enable", CONFIG_HLP_LDPC_OFFLOAD, PARAMFLAG_BOOL, .iptr=&LDPC_OFFLOAD_FLAG, .defstrval=0, TYPE_INT, 0}, \ {"sync-ref", CONFIG_HLP_SYNC_REF, 0, .uptr=&SYNC_REF, .defintval=0, TYPE_UINT, 0}, \ + {"A" , CONFIG_HLP_TADV, 0, .iptr=&softmodem_params.command_line_sample_advance,.defintval=0, TYPE_INT, 0}, \ + {"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, .iptr=&softmodem_params.threequarter_fs, .defintval=0, TYPE_INT, 0}, \ } // clang-format on @@ -236,6 +243,7 @@ extern int usrp_tx_thread; { .s5 = { NULL } }, \ { .s5 = { NULL } }, \ { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ } // clang-format on @@ -332,7 +340,7 @@ typedef struct { uint32_t clock_source; uint32_t timing_source; double tune_offset; - int hw_timing_advance; + int command_line_sample_advance; uint32_t send_dmrs_sync; int use_256qam_table; int chest_time; @@ -346,16 +354,17 @@ typedef struct { uint32_t sync_ref; int no_itti; int ldpc_offload_flag; + int threequarter_fs; } softmodem_params_t; -extern uint64_t get_softmodem_optmask(void); -extern uint64_t set_softmodem_optmask(uint64_t bitmask); -extern uint64_t clear_softmodem_optmask(uint64_t bitmask); -extern softmodem_params_t *get_softmodem_params(void); -extern void get_common_options(configmodule_interface_t *cfg, uint32_t execmask); -extern char *get_softmodem_function(uint64_t *sofmodemfunc_mask_ptr); +uint64_t get_softmodem_optmask(void); +uint64_t set_softmodem_optmask(uint64_t bitmask); +uint64_t clear_softmodem_optmask(uint64_t bitmask); +softmodem_params_t *get_softmodem_params(void); +void get_common_options(configmodule_interface_t *cfg, uint32_t execmask); +char *get_softmodem_function(uint64_t *sofmodemfunc_mask_ptr); #define SOFTMODEM_RTSIGNAL (SIGRTMIN+1) -extern void set_softmodem_sighandler(void); +void set_softmodem_sighandler(void); extern uint64_t downlink_frequency[MAX_NUM_CCs][4]; extern int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; extern int usrp_tx_thread; diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h index 7364b66308..42090c2e9e 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h @@ -547,6 +547,7 @@ typedef struct { int ta_frame; int ta_slot; int ta_command; + bool is_rar; } fapi_nr_ta_command_pdu; typedef struct { diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index 06c26b6923..c864a0366a 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -19,6 +19,7 @@ * contact@openairinterface.org */ +#include "executables/softmodem-common.h" #include "executables/nr-softmodem-common.h" #include "common/utils/nr/nr_common.h" #include "common/ran_context.h" @@ -540,7 +541,7 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config) LOG_I(PHY, "DL frequency %lu Hz, UL frequency %lu Hz: band %d, uldl offset %d Hz\n", fp->dl_CarrierFreq, fp->ul_CarrierFreq, fp->nr_band, dlul_offset); - fp->threequarter_fs = openair0_cfg[0].threequarter_fs; + fp->threequarter_fs = get_softmodem_params()->threequarter_fs; LOG_A(PHY,"Configuring MIB for instance %d, : (Nid_cell %d,DL freq %llu, UL freq %llu)\n", Mod_id, gNB_config->cell_config.phy_cell_id.value, diff --git a/openair1/PHY/LTE_UE_TRANSPORT/prach_ue.c b/openair1/PHY/LTE_UE_TRANSPORT/prach_ue.c index 5470766827..defca14570 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/prach_ue.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/prach_ue.c @@ -81,13 +81,9 @@ 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; - prach_start = (ue->rx_offset+subframe*ue->frame_parms.samples_per_tti-ue->hw_timing_advance-ue->N_TA_offset); + prach_start = (ue->rx_offset + subframe * ue->frame_parms.samples_per_tti - 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, - prach_start, - ue->rx_offset, - ue->hw_timing_advance, - ue->N_TA_offset); + LOG_I(PHY, "[UE %d] prach_start %d, rx_offset %d, N_TA_offset %d\n", ue->Mod_id, prach_start, ue->rx_offset, ue->N_TA_offset); #endif if (prach_start<0) diff --git a/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c b/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c index 260677890f..0f68620048 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c +++ b/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c @@ -206,9 +206,19 @@ void nr_gnb_measurements(PHY_VARS_gNB *gNB, int rx_power_tot = 0; unsigned short rx_power_avg_dB; unsigned short rx_power_tot_dB; - - double rx_gain = openair0_cfg[0].rx_gain[0]; - double rx_gain_offset = openair0_cfg[0].rx_gain_offset[0]; + RU_t *ru = gNB->RU_list[0]; + double rx_gain, rx_gain_offset; + if (ru && ru->rfdevice.openair0_cfg) { + rx_gain = ru->rfdevice.openair0_cfg->rx_gain[0]; + rx_gain_offset = ru->rfdevice.openair0_cfg->rx_gain_offset[0]; + } else if (ru && ru->ifdevice.openair0_cfg) { + rx_gain = ru->ifdevice.openair0_cfg->rx_gain[0]; + rx_gain_offset = ru->ifdevice.openair0_cfg->rx_gain_offset[0]; + } else { + LOG_W(NR_PHY, "no device for rx gain, take arbitrary gain = 1)\n"); + rx_gain = 1; + rx_gain_offset = 0; + } PHY_MEASUREMENTS_gNB *meas = &gNB->measurements; NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; int ch_offset = fp->ofdm_symbol_size * symbol; diff --git a/openair1/PHY/defs_L1_NB_IoT.h b/openair1/PHY/defs_L1_NB_IoT.h index 01143ccf47..38996e20a0 100644 --- a/openair1/PHY/defs_L1_NB_IoT.h +++ b/openair1/PHY/defs_L1_NB_IoT.h @@ -637,8 +637,6 @@ typedef struct PHY_VARS_eNB_NB_IoT_s { /// uint32_t total_system_throughput; /// - int hw_timing_advance; - /// time_stats_t phy_proc; time_stats_t phy_proc_tx; time_stats_t phy_proc_rx; @@ -873,7 +871,6 @@ typedef struct { int rx_offset; /// Timing offset int rx_offset_diff; /// Timing adjustment for ofdm symbol0 on HW USRP int timing_advance; ///timing advance signalled from eNB - int hw_timing_advance; int N_TA_offset; ///timing offset used in TDD /// Flag to tell if UE is secondary user (cognitive mode) unsigned char is_secondary_ue; diff --git a/openair1/PHY/defs_UE.h b/openair1/PHY/defs_UE.h index 7f1858b2c4..06eaf4a15d 100644 --- a/openair1/PHY/defs_UE.h +++ b/openair1/PHY/defs_UE.h @@ -721,8 +721,7 @@ typedef struct { int rx_offset; /// Timing offset int rx_offset_diff; /// Timing adjustment for ofdm symbol0 on HW USRP int time_sync_cell; - int timing_advance; ///timing advance signalled from eNB - int hw_timing_advance; + int timing_advance; /// timing advance signalled from eNB int N_TA_offset; ///timing offset used in TDD /// Flag to tell if UE is secondary user (cognitive mode) unsigned char is_secondary_ue; diff --git a/openair1/PHY/defs_eNB.h b/openair1/PHY/defs_eNB.h index 45abb05c2f..389f15e82b 100644 --- a/openair1/PHY/defs_eNB.h +++ b/openair1/PHY/defs_eNB.h @@ -713,8 +713,6 @@ typedef struct PHY_VARS_eNB_s { uint32_t total_transmitted_bits; uint32_t total_system_throughput; - int hw_timing_advance; - time_stats_t phy_proc_tx; time_stats_t phy_proc_rx; time_stats_t rx_prach; diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index c4d6e2ff91..72233f58cf 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -175,7 +175,7 @@ struct NR_DL_FRAME_PARMS { /// subcarrier spacing (15,30,60,120) uint32_t subcarrier_spacing; /// 3/4 sampling - uint8_t threequarter_fs; + int threequarter_fs; /// Size of FFT uint16_t ofdm_symbol_size; /// Number of prefix samples in all but first symbol of slot diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c index fbe04ffb84..0ec735caa0 100644 --- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c +++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c @@ -320,7 +320,7 @@ static void configure_dlsch(NR_UE_DLSCH_t *dlsch0, } } -void configure_ta_command(PHY_VARS_NR_UE *ue, fapi_nr_ta_command_pdu *ta_command_pdu) +static void configure_ta_command(PHY_VARS_NR_UE *ue, fapi_nr_ta_command_pdu *ta_command_pdu) { /* Time Alignment procedure @@ -365,13 +365,19 @@ void configure_ta_command(PHY_VARS_NR_UE *ue, fapi_nr_ta_command_pdu *ta_command const double t_subframe = 1.0; // subframe duration of 1 msec const int ul_tx_timing_adjustment = 1 + (int)ceil(slots_per_subframe*(N_t_1 + N_t_2 + N_TA_max + 0.5)/t_subframe); - ue->ta_slot = (ta_command_pdu->ta_slot + ul_tx_timing_adjustment) % slots_per_frame; - if (ta_command_pdu->ta_slot + ul_tx_timing_adjustment > slots_per_frame) - ue->ta_frame = (ta_command_pdu->ta_frame + 1) % 1024; - else + if (ta_command_pdu->is_rar) { + ue->ta_slot = ta_command_pdu->ta_slot; ue->ta_frame = ta_command_pdu->ta_frame; - - ue->ta_command = ta_command_pdu->ta_command; + ue->timing_advance = 0; + ue->ta_command = ta_command_pdu->ta_command + 31; // To use TA adjustment algo in ue_ta_procedures() + } else { + ue->ta_slot = (ta_command_pdu->ta_slot + ul_tx_timing_adjustment) % slots_per_frame; + if (ta_command_pdu->ta_slot + ul_tx_timing_adjustment > slots_per_frame) + ue->ta_frame = (ta_command_pdu->ta_frame + 1) % 1024; + else + ue->ta_frame = ta_command_pdu->ta_frame; + ue->ta_command = ta_command_pdu->ta_command; + } LOG_D(PHY,"TA command received in Frame.Slot %d.%d -- Starting UL time alignment procedures. TA update will be applied at frame %d slot %d\n", ta_command_pdu->ta_frame, ta_command_pdu->ta_slot, ue->ta_frame, ue->ta_slot); } diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 1a2e410071..dba954aa71 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -232,15 +232,14 @@ int get_tx_amp_prach(int power_dBm, int power_max_dBm, int N_RB_UL){ // - If the current tx frame and slot match the TA configuration // then timing advance is processed and set to be applied in the next UL transmission // - Application of timing adjustment according to TS 38.213 p4.2 -// todo: // - handle RAR TA application as per ch 4.2 TS 38.213 void ue_ta_procedures(PHY_VARS_NR_UE *ue, int slot_tx, int frame_tx) { if (frame_tx == ue->ta_frame && slot_tx == ue->ta_slot) { - uint16_t ofdm_symbol_size = ue->frame_parms.ofdm_symbol_size; - // convert time factor "16 * 64 * T_c / (2^mu)" in N_TA calculation in TS38.213 section 4.2 to samples by multiplying with samples per second + // convert time factor "16 * 64 * T_c / (2^mu)" in N_TA calculation in TS38.213 section 4.2 to samples by multiplying with + // samples per second // 16 * 64 * T_c / (2^mu) * samples_per_second // = 16 * T_s / (2^mu) * samples_per_second // = 16 * 1 / (15 kHz * 2048) / (2^mu) * (15 kHz * 2^mu * ofdm_symbol_size) @@ -250,7 +249,8 @@ void ue_ta_procedures(PHY_VARS_NR_UE *ue, int slot_tx, int frame_tx) ue->timing_advance += (ue->ta_command - 31) * bw_scaling; - LOG_D(PHY, "[UE %d] [%d.%d] Got timing advance command %u from MAC, new value is %d\n", + LOG_D(PHY, + "[UE %d] [%d.%d] Got timing advance command %u from MAC, new value is %d\n", ue->Mod_id, frame_tx, slot_tx, diff --git a/openair1/SCHED_UE/phy_procedures_lte_ue.c b/openair1/SCHED_UE/phy_procedures_lte_ue.c index 61429afc9e..7892857051 100644 --- a/openair1/SCHED_UE/phy_procedures_lte_ue.c +++ b/openair1/SCHED_UE/phy_procedures_lte_ue.c @@ -1151,8 +1151,7 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, nsymb = (frame_parms->Ncp == 0) ? 14 : 12; - ulsch_start = ue->rx_offset + subframe_tx * frame_parms->samples_per_tti - - ue->hw_timing_advance - ue->timing_advance - ue->N_TA_offset + 5; + ulsch_start = ue->rx_offset + subframe_tx * frame_parms->samples_per_tti - ue->timing_advance - ue->N_TA_offset + 5; if(ulsch_start < 0) ulsch_start = ulsch_start + (LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti); @@ -1210,16 +1209,6 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, ((short *)ue->common_vars.txdata[aa])[2*k] = ((short *)dummy_tx_buffer)[2*l]; ((short *)ue->common_vars.txdata[aa])[2*k+1] = ((short *)dummy_tx_buffer)[2*l+1]; } - - /* - only for debug - LOG_I(PHY,"ul-signal [subframe: %d, ulsch_start %d, TA: %d, rxOffset: %d, timing_advance: %d, hw_timing_advance: %d]\n",subframe_tx, ulsch_start, ue->N_TA_offset, ue->rx_offset, ue->timing_advance, ue->hw_timing_advance); - if( (crash == 1) && (subframe_tx == 0) ) - { - LOG_E(PHY,"***** DUMP TX Signal [ulsch_start %d] *****\n",ulsch_start); - LOG_M("txBuff.m","txSignal",&ue->common_vars.txdata[aa][ulsch_start],frame_parms->samples_per_tti,1,1); - } - */ } //nb_antennas_tx if ( LOG_DEBUGFLAG(UE_TIMING)) { diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 0e64d837e0..f4f6e891b2 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -552,6 +552,8 @@ int main(int argc, char *argv[]) gNB = RC.gNB[0]; gNB->ofdm_offset_divisor = UINT_MAX; gNB->num_pusch_symbols_per_thread = 1; + gNB->RU_list[0] = calloc(1, sizeof(**gNB->RU_list)); + gNB->RU_list[0]->rfdevice.openair0_cfg = openair0_cfg; initFloatingCoresTpool(threadCnt, &gNB->threadPool, false, "gNB-tpool"); initNotifiedFIFO(&gNB->respDecode); diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index 4bc3a6df16..1b786af544 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -384,11 +384,16 @@ typedef struct { short ssb_rsrp_dBm; } NR_SSB_meas_t; +typedef enum ta_type { + no_ta = 0, + adjustment_ta, + rar_ta, +} ta_type_t; + typedef struct NR_UL_TIME_ALIGNMENT { /// TA command and TAGID received from the gNB - bool ta_apply; + ta_type_t ta_apply; int ta_command; - int ta_total; uint32_t tag_id; int frame; int slot; diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index 8397faaddf..d553781498 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -401,7 +401,6 @@ and fills the PRACH PDU per each FD occasion. void nr_ue_pucch_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, int slotP, void *phy_data); void nr_schedule_csirs_reception(NR_UE_MAC_INST_t *mac, int frame, int slot); void nr_schedule_csi_for_im(NR_UE_MAC_INST_t *mac, int frame, int slot); -void schedule_ta_command(fapi_nr_dl_config_request_t *dl_config, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment); /* \brief This function schedules the Msg3 transmission @param diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index a5df641f4a..6add9f025c 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -3645,14 +3645,7 @@ void nr_ue_process_mac_pdu(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_i } if (mac_len > 0) { - LOG_D(NR_MAC,"DL_SCH_LCID_CCCH (e.g. RRCSetup) with payload len %d\n", mac_len); - for (int i = 0; i < mac_subheader_len; i++) { - LOG_D(NR_MAC, "MAC header %d: 0x%x\n", i, pduP[i]); - } - for (int i = 0; i < mac_len; i++) { - LOG_D(NR_MAC, "%d: 0x%x\n", i, pduP[mac_subheader_len + i]); - } - + LOG_DDUMP(NR_MAC, (void *)pduP, mac_subheader_len + mac_len, LOG_DUMP_CHAR, "DL_SCH_LCID_CCCH (e.g. RRCSetup) payload: "); mac_rlc_data_ind(mac->ue_id, mac->ue_id, gNB_index, @@ -3729,12 +3722,11 @@ void nr_ue_process_mac_pdu(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_i const int tag = ((NR_MAC_CE_TA *)pduP)[1].TAGID; NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &mac->ul_time_alignment; - ul_time_alignment->ta_total += ta - 31; ul_time_alignment->tag_id = tag; ul_time_alignment->ta_command = ta; ul_time_alignment->frame = frameP; ul_time_alignment->slot = slot; - ul_time_alignment->ta_apply = true; + ul_time_alignment->ta_apply = adjustment_ta; /* #ifdef DEBUG_HEADER_PARSING LOG_D(MAC, "[UE] CE %d : UE Timing Advance : %d\n", i, pduP[1]); @@ -3742,21 +3734,9 @@ void nr_ue_process_mac_pdu(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_i */ if (ta == 31) - LOG_D(NR_MAC, "[%d.%d] Received TA_COMMAND %u TAGID %u CC_id %d TA total %d\n", - frameP, - slot, - ta, - tag, - CC_id, - ul_time_alignment->ta_total); + LOG_D(NR_MAC, "[%d.%d] Received TA_COMMAND %u TAGID %u CC_id %d \n", frameP, slot, ta, tag, CC_id); else - LOG_I(NR_MAC, "[%d.%d] Received TA_COMMAND %u TAGID %u CC_id %d TA total %d\n", - frameP, - slot, - ta, - tag, - CC_id, - ul_time_alignment->ta_total); + LOG_I(NR_MAC, "[%d.%d] Received TA_COMMAND %u TAGID %u CC_id %d \n", frameP, slot, ta, tag, CC_id); break; case DL_SCH_LCID_CON_RES_ID: @@ -4136,9 +4116,9 @@ static void nr_ue_process_rar(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *d // TA command NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &mac->ul_time_alignment; const int ta = rar->TA2 + (rar->TA1 << 5); - ul_time_alignment->ta_command = 31 + ta; - ul_time_alignment->ta_total = ta; - ul_time_alignment->ta_apply = true; + ul_time_alignment->ta_command = ta; + ul_time_alignment->ta_apply = rar_ta; + LOG_W(MAC, "received TA command %d\n", 31 + ta); #ifdef DEBUG_RAR // CSI @@ -4228,6 +4208,8 @@ static void nr_ue_process_rar(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *d return; } ret = nr_ue_pusch_scheduler(mac, is_Msg3, frame, slot, &frame_tx, &slot_tx, tda_info.k2); + ul_time_alignment->frame = frame_tx; + ul_time_alignment->slot = slot_tx; if (ret != -1) { uint16_t rnti = mac->crnti; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 61324e8949..dc5da31ca9 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -58,6 +58,7 @@ //#define SRS_DEBUG static void nr_ue_prach_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, sub_frame_t slotP); +static void schedule_ta_command(fapi_nr_dl_config_request_t *dl_config, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment); fapi_nr_ul_config_request_pdu_t *lockGet_ul_config(NR_UE_MAC_INST_t *mac, frame_t frame_tx, int slot_tx, uint8_t pdu_type) { @@ -1018,7 +1019,7 @@ void nr_ue_dl_scheduler(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_info ue_dci_configuration(mac, dl_config, rx_frame, rx_slot); - if (mac->ul_time_alignment.ta_apply) + if (mac->ul_time_alignment.ta_apply != no_ta) schedule_ta_command(dl_config, &mac->ul_time_alignment); if (mac->state == UE_CONNECTED) { nr_schedule_csirs_reception(mac, rx_frame, rx_slot); @@ -3357,15 +3358,16 @@ uint8_t nr_ue_get_sdu(NR_UE_MAC_INST_t *mac, return num_sdus > 0 ? 1 : 0; } -void schedule_ta_command(fapi_nr_dl_config_request_t *dl_config, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment) +static void schedule_ta_command(fapi_nr_dl_config_request_t *dl_config, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment) { fapi_nr_ta_command_pdu *ta = &dl_config->dl_config_list[dl_config->number_pdus].ta_command_pdu; ta->ta_frame = ul_time_alignment->frame; ta->ta_slot = ul_time_alignment->slot; + ta->is_rar = ul_time_alignment->ta_apply == rar_ta; ta->ta_command = ul_time_alignment->ta_command; dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_CONFIG_TA_COMMAND; dl_config->number_pdus += 1; - ul_time_alignment->ta_apply = false; + ul_time_alignment->ta_apply = no_ta; } uint32_t nr_get_pbr(long prioritizedbitrate) diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index 270441a6dd..9abb5ab748 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -104,263 +104,320 @@ nfapi_nr_pm_list_t init_DL_MIMO_codebook(gNB_MAC_INST *gNB, nr_pdsch_AntennaPort nfapi_nr_pm_pdu_t *pmi_pdu = malloc16(mat.num_pm_idx * sizeof(*pmi_pdu)); AssertFatal(pmi_pdu != NULL, "out of memory\n"); mat.pmi_pdu = pmi_pdu; + AssertFatal(num_antenna_ports < 16, "Max number of antenna ports supported is currently 16\n"); // Generation of codebook Type1 with codebookMode 1 (num_antenna_ports < 16) - if (num_antenna_ports < 16) { - //Generate DFT vertical beams - //ll: index of a vertical beams vector (represented by i1_1 in TS 38.214) - const int max_l = N1 * O1 + (K1 - 1) * O1; - double complex v[max_l][N1]; - for (int ll = 0; ll < max_l; ll++) { //i1_1 - for (int nn = 0; nn < N1; nn++) { - v[ll][nn] = cexp(I * (2 * M_PI * nn * ll) / (N1 * O1)); - LOG_D(PHY,"v[%d][%d] = %f +j %f\n", ll, nn, creal(v[ll][nn]), cimag(v[ll][nn])); - } + // Generate DFT vertical beams + // ll: index of a vertical beams vector (represented by i1_1 in TS 38.214) + const int max_l = N1 * O1 + (K1 - 1) * O1; + double complex v[max_l][N1]; + for (int ll = 0; ll < max_l; ll++) { // i1_1 + for (int nn = 0; nn < N1; nn++) { + v[ll][nn] = cexp(I * (2 * M_PI * nn * ll) / (N1 * O1)); + LOG_D(PHY, "v[%d][%d] = %f +j %f\n", ll, nn, creal(v[ll][nn]), cimag(v[ll][nn])); } - //Generate DFT Horizontal beams - //mm: index of a Horizontal beams vector (represented by i1_2 in TS 38.214) - const int max_m = N2 * O2 + (K2 - 1) * O2; - double complex u[max_m][N2]; - for (int mm = 0; mm < max_m; mm++) { //i1_2 - for (int nn = 0; nn < N2; nn++) { - u[mm][nn] = cexp(I * (2 * M_PI * nn * mm) / (N2 * O2)); - LOG_D(PHY,"u[%d][%d] = %f +j %f\n", mm, nn, creal(u[mm][nn]), cimag(u[mm][nn])); - } - } - //Generate co-phasing angles - //i_2: index of a co-phasing vector - //i1_1, i1_2, and i_2 are reported from UEs - double complex theta_n[4]; - for (int nn = 0; nn < 4; nn++) { - theta_n[nn] = cexp(I * M_PI * nn / 2); - LOG_D(PHY,"theta_n[%d] = %f +j %f\n", nn, creal(theta_n[nn]), cimag(theta_n[nn])); - } - //Kronecker product v_lm - double complex v_lm[max_l][max_m][N2 * N1]; - //v_ll_mm_codebook denotes the elements of a precoding matrix W_i1,1_i_1,2 - for(int ll = 0; ll < max_l; ll++) { //i_1_1 - for (int mm = 0; mm < max_m; mm++) { //i_1_2 - for (int nn1 = 0; nn1 < N1; nn1++) { - for (int nn2 = 0; nn2 < N2; nn2++) { - v_lm[ll][mm][nn1 * N2 + nn2] = v[ll][nn1] * u[mm][nn2]; - LOG_D(PHY,"v_lm[%d][%d][%d] = %f +j %f\n",ll, mm, nn1 * N2 + nn2, creal(v_lm[ll][mm][nn1*N2+nn2]), cimag(v_lm[ll][mm][nn1*N2+nn2])); - } - } - } - } - - double complex res_code; - - //Table 5.2.2.2.1-5: - int pmiq = 0; - //Codebook for 1-layer CSI reporting using antenna ports 3000 to 2999+PCSI-RS - for(int ll = 0; ll < N1 * O1; ll++) { //i_1_1 - for (int mm = 0; mm < N2 * O2; mm++) { //i_1_2 - for (int nn = 0; nn < 4; nn++) { - pmiq = ll * N2 * O2 * 4 + mm * 4 + nn; - pmi_pdu[pmiq].pm_idx = pmiq + 1; // index 0 is the identity matrix - pmi_pdu[pmiq].numLayers = 1; - pmi_pdu[pmiq].num_ant_ports = num_antenna_ports; - LOG_D(PHY, "layer 1 Codebook pmiq = %d\n", pmiq); - for (int len = 0; len < N1 * N2; len++) { - nfapi_nr_pm_weights_t *weights = &pmi_pdu[pmiq].weights[0][len]; - res_code = sqrt( 1 /(double)num_antenna_ports) * v_lm[ll][mm][len]; - c16_t precoder_weight = convert_precoder_weight(res_code); - weights->precoder_weight_Re = precoder_weight.r; - weights->precoder_weight_Im = precoder_weight.i; - LOG_D(PHY, "1 Layer Precoding Matrix[0][pmi %d][antPort %d]= %f+j %f -> Fixed Point %d+j %d \n", - pmiq, len, creal(res_code), cimag(res_code), weights->precoder_weight_Re, weights->precoder_weight_Im); - } - - for(int len = N1 * N2; len < 2 * N1 * N2; len++) { - nfapi_nr_pm_weights_t *weights = &pmi_pdu[pmiq].weights[0][len]; - res_code = sqrt(1 / (double)num_antenna_ports) * theta_n[nn] * v_lm[ll][mm][len-N1*N2]; - c16_t precoder_weight = convert_precoder_weight(res_code); - weights->precoder_weight_Re = precoder_weight.r; - weights->precoder_weight_Im = precoder_weight.i; - LOG_D(PHY, "1 Layer Precoding Matrix[0][pmi %d][antPort %d]= %f+j %f -> Fixed Point %d+j %d \n", - pmiq, len, creal(res_code), cimag(res_code), weights->precoder_weight_Re, weights->precoder_weight_Im); - } - } - } - } - int llc = 0; - int mmc = 0; - double complex phase_sign = 0; - //Table 5.2.2.2.1-6: - //Codebook for 2-layer CSI reporting using antenna ports 3000 to 2999+PCSI-RS - //Compute the code book size for generating 2 layers out of Tx antenna ports - - //pmi=1,...,pmi_size, we construct - for(int ll = 0; ll < N1 * O1; ll++) { //i_1_1 - for (int mm = 0; mm < N2 * O2; mm++) { // i_1_2 - for(int k1 = 0; k1 < K1; k1++) { - for (int k2 = 0; k2 < K2; k2++) { - for (int nn = 0; nn < 2; nn++) { // i_2 - pmiq ++; - pmi_pdu[pmiq].pm_idx = pmiq + 1; // index 0 is the identity matrix - pmi_pdu[pmiq].numLayers = 2; - pmi_pdu[pmiq].num_ant_ports = num_antenna_ports; - LOG_D(PHY, "layer 2 Codebook pmiq = %d\n", pmiq); - for(int j_col = 0; j_col < 2; j_col++) { - if (j_col == 0) { - llc = ll; - mmc = mm; - phase_sign = 1; - } - if (j_col == 1) { - llc = ll + k1 * O1; - mmc = mm + k2 * O2; - phase_sign = -1; - } - for (int i_rows = 0; i_rows < N1 * N2; i_rows++) { - nfapi_nr_pm_weights_t *weights = &pmi_pdu[pmiq].weights[j_col][i_rows]; - res_code = sqrt(1 / (double)(2 * num_antenna_ports)) * v_lm[llc][mmc][i_rows]; - c16_t precoder_weight = convert_precoder_weight(res_code); - weights->precoder_weight_Re = precoder_weight.r; - weights->precoder_weight_Im = precoder_weight.i; - LOG_D(PHY, "2 Layer Precoding Matrix[1][pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d \n", - pmiq, i_rows, j_col, creal(res_code), cimag(res_code), weights->precoder_weight_Re, weights->precoder_weight_Im); - } - for (int i_rows = N1 * N2; i_rows < 2 * N1 * N2; i_rows++) { - nfapi_nr_pm_weights_t *weights = &pmi_pdu[pmiq].weights[j_col][i_rows]; - res_code = sqrt(1 / (double)(2 * num_antenna_ports)) * (phase_sign) * theta_n[nn] * v_lm[llc][mmc][i_rows - N1 * N2]; - c16_t precoder_weight = convert_precoder_weight(res_code); - weights->precoder_weight_Re = precoder_weight.r; - weights->precoder_weight_Im = precoder_weight.i; - LOG_D(PHY, "2 Layer Precoding Matrix[1][pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d \n", - pmiq, i_rows, j_col, creal(res_code), cimag(res_code), weights->precoder_weight_Re, weights->precoder_weight_Im); - } - } - } - } - } - } - } - - if(max_mimo_layers < 3) - return mat; - - //Table 5.2.2.2.1-7: - //Codebook for 3-layer CSI reporting using antenna ports 3000 to 2999+PCSI-RS - - //pmi=1,...,pmi_size are computed as follows - for(int ll = 0; ll < N1 * O1; ll++) { //i_1_1 - for (int mm = 0; mm < N2 * O2; mm++) { // i_1_2 - for(int k1 = 0; k1 < K1; k1++) { - for (int k2 = 0; k2 < K2; k2++) { - for (int nn = 0; nn < 2; nn++) { // i_2 - pmiq ++; - pmi_pdu[pmiq].pm_idx = pmiq + 1; // index 0 is the identity matrix - pmi_pdu[pmiq].numLayers = 3; - pmi_pdu[pmiq].num_ant_ports = num_antenna_ports; - LOG_D(PHY, "layer 3 Codebook pmiq = %d\n",pmiq); - for(int j_col = 0; j_col < 3; j_col++) { - if (j_col == 0) { - llc = ll; - mmc = mm; - phase_sign = 1; - } - if (j_col==1) { - llc = ll + k1 * O1; - mmc = mm + k2 * O2; - phase_sign = 1; - } - if (j_col==2) { - llc = ll; - mmc = mm; - phase_sign = -1; - } - for (int i_rows = 0; i_rows < N1 * N2; i_rows++) { - nfapi_nr_pm_weights_t *weights = &pmi_pdu[pmiq].weights[j_col][i_rows]; - res_code = sqrt(1 / (double)(3 * num_antenna_ports)) * v_lm[llc][mmc][i_rows]; - c16_t precoder_weight = convert_precoder_weight(res_code); - weights->precoder_weight_Re = precoder_weight.r; - weights->precoder_weight_Im = precoder_weight.i; - LOG_D(PHY, "3 Layer Precoding Matrix[1][pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d \n", - pmiq, i_rows, j_col, creal(res_code), cimag(res_code), weights->precoder_weight_Re, weights->precoder_weight_Im); - } - for (int i_rows = N1 * N2; i_rows < 2 * N1 * N2; i_rows++) { - nfapi_nr_pm_weights_t *weights = &pmi_pdu[pmiq].weights[j_col][i_rows]; - res_code=sqrt(1 / (double)(3 * num_antenna_ports)) * (phase_sign) * theta_n[nn] * v_lm[llc][mmc][i_rows - N1 * N2]; - c16_t precoder_weight = convert_precoder_weight(res_code); - weights->precoder_weight_Re = precoder_weight.r; - weights->precoder_weight_Im = precoder_weight.i; - LOG_D(PHY, "3 Layer Precoding Matrix[1][pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d \n", - pmiq, i_rows, j_col, creal(res_code), cimag(res_code), weights->precoder_weight_Re, weights->precoder_weight_Im); - } - } - } - } - } - } - } - - if(max_mimo_layers < 4) - return mat; - - //Table 5.2.2.2.1-8: - //Codebook for 4-layer CSI reporting using antenna ports 3000 to 2999+PCSI-RS - - for(int ll = 0; ll < N1 * O1; ll++) { //i_1_1 - for (int mm = 0; mm < N2 * O2; mm++) { // i_1_2 - for(int k1 = 0; k1 < K1; k1++) { - for (int k2 = 0; k2 < K2; k2++) { - for (int nn = 0; nn < 2; nn++) { // i_2 - pmiq ++; - pmi_pdu[pmiq].pm_idx = pmiq + 1; // index 0 is the identity matrix - pmi_pdu[pmiq].numLayers = 4; - pmi_pdu[pmiq].num_ant_ports = num_antenna_ports; - LOG_D(PHY, "layer 4 pmiq = %d\n", pmiq); - for(int j_col = 0; j_col < 4; j_col++) { - if (j_col == 0) { - llc = ll; - mmc = mm; - phase_sign = 1; - } - if (j_col == 1) { - llc = ll + k1 * O1; - mmc = mm + k2 * O2; - phase_sign = 1; - } - if (j_col == 2) { - llc = ll; - mmc = mm; - phase_sign = -1; - } - if (j_col == 3) { - llc = ll + k1 * O1; - mmc = mm + k2 * O2; - phase_sign = -1; - } - for (int i_rows = 0; i_rows < N1 * N2; i_rows++) { - nfapi_nr_pm_weights_t *weights = &pmi_pdu[pmiq].weights[j_col][i_rows]; - res_code=sqrt(1 / (double)(4 * num_antenna_ports)) * v_lm[llc][mmc][i_rows]; - c16_t precoder_weight = convert_precoder_weight(res_code); - weights->precoder_weight_Re = precoder_weight.r; - weights->precoder_weight_Im = precoder_weight.i; - LOG_D(PHY, "4 Layer Precoding Matrix[1][pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d \n", - pmiq, i_rows, j_col, creal(res_code), cimag(res_code), weights->precoder_weight_Re, weights->precoder_weight_Im); - } - for (int i_rows = N1 * N2; i_rows < 2 * N1 * N2; i_rows++) { - nfapi_nr_pm_weights_t *weights = &pmi_pdu[pmiq].weights[j_col][i_rows]; - res_code=sqrt(1 / (double)(4 * num_antenna_ports)) * (phase_sign) * theta_n[nn] * v_lm[llc][mmc][i_rows - N1 * N2]; - c16_t precoder_weight = convert_precoder_weight(res_code); - weights->precoder_weight_Re = precoder_weight.r; - weights->precoder_weight_Im = precoder_weight.i; - LOG_D(PHY, "4 Layer Precoding Matrix[1][pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d \n", - pmiq, i_rows, j_col, creal(res_code), cimag(res_code), weights->precoder_weight_Re, weights->precoder_weight_Im); - } - } - } - } - } - } - } - return mat; } - else - AssertFatal(false, "Max number of antenna ports supported is currently 16\n"); + // Generate DFT Horizontal beams + // mm: index of a Horizontal beams vector (represented by i1_2 in TS 38.214) + const int max_m = N2 * O2 + (K2 - 1) * O2; + double complex u[max_m][N2]; + for (int mm = 0; mm < max_m; mm++) { // i1_2 + for (int nn = 0; nn < N2; nn++) { + u[mm][nn] = cexp(I * (2 * M_PI * nn * mm) / (N2 * O2)); + LOG_D(PHY, "u[%d][%d] = %f +j %f\n", mm, nn, creal(u[mm][nn]), cimag(u[mm][nn])); + } + } + // Generate co-phasing angles + // i_2: index of a co-phasing vector + // i1_1, i1_2, and i_2 are reported from UEs + double complex theta_n[4]; + for (int nn = 0; nn < 4; nn++) { + theta_n[nn] = cexp(I * M_PI * nn / 2); + LOG_D(PHY, "theta_n[%d] = %f +j %f\n", nn, creal(theta_n[nn]), cimag(theta_n[nn])); + } + // Kronecker product v_lm + double complex v_lm[max_l][max_m][N2 * N1]; + // v_ll_mm_codebook denotes the elements of a precoding matrix W_i1,1_i_1,2 + for (int ll = 0; ll < max_l; ll++) { // i_1_1 + for (int mm = 0; mm < max_m; mm++) { // i_1_2 + for (int nn1 = 0; nn1 < N1; nn1++) { + for (int nn2 = 0; nn2 < N2; nn2++) { + v_lm[ll][mm][nn1 * N2 + nn2] = v[ll][nn1] * u[mm][nn2]; + LOG_D(PHY, + "v_lm[%d][%d][%d] = %f +j %f\n", + ll, + mm, + nn1 * N2 + nn2, + creal(v_lm[ll][mm][nn1 * N2 + nn2]), + cimag(v_lm[ll][mm][nn1 * N2 + nn2])); + } + } + } + } + + double complex res_code; + + // Table 5.2.2.2.1-5: + int pmiq = 0; + // Codebook for 1-layer CSI reporting using antenna ports 3000 to 2999+PCSI-RS + for (int ll = 0; ll < N1 * O1; ll++) { // i_1_1 + for (int mm = 0; mm < N2 * O2; mm++) { // i_1_2 + for (int nn = 0; nn < 4; nn++) { + pmiq = ll * N2 * O2 * 4 + mm * 4 + nn; + pmi_pdu[pmiq].pm_idx = pmiq + 1; // index 0 is the identity matrix + pmi_pdu[pmiq].numLayers = 1; + pmi_pdu[pmiq].num_ant_ports = num_antenna_ports; + LOG_D(PHY, "layer 1 Codebook pmiq = %d\n", pmiq); + for (int len = 0; len < N1 * N2; len++) { + nfapi_nr_pm_weights_t *weights = &pmi_pdu[pmiq].weights[0][len]; + res_code = sqrt(1 / (double)num_antenna_ports) * v_lm[ll][mm][len]; + c16_t precoder_weight = convert_precoder_weight(res_code); + weights->precoder_weight_Re = precoder_weight.r; + weights->precoder_weight_Im = precoder_weight.i; + LOG_D(PHY, + "1 Layer Precoding Matrix[0][pmi %d][antPort %d]= %f+j %f -> Fixed Point %d+j %d \n", + pmiq, + len, + creal(res_code), + cimag(res_code), + weights->precoder_weight_Re, + weights->precoder_weight_Im); + } + + for (int len = N1 * N2; len < 2 * N1 * N2; len++) { + nfapi_nr_pm_weights_t *weights = &pmi_pdu[pmiq].weights[0][len]; + res_code = sqrt(1 / (double)num_antenna_ports) * theta_n[nn] * v_lm[ll][mm][len - N1 * N2]; + c16_t precoder_weight = convert_precoder_weight(res_code); + weights->precoder_weight_Re = precoder_weight.r; + weights->precoder_weight_Im = precoder_weight.i; + LOG_D(PHY, + "1 Layer Precoding Matrix[0][pmi %d][antPort %d]= %f+j %f -> Fixed Point %d+j %d \n", + pmiq, + len, + creal(res_code), + cimag(res_code), + weights->precoder_weight_Re, + weights->precoder_weight_Im); + } + } + } + } + int llc = 0; + int mmc = 0; + double complex phase_sign = 0; + // Table 5.2.2.2.1-6: + // Codebook for 2-layer CSI reporting using antenna ports 3000 to 2999+PCSI-RS + // Compute the code book size for generating 2 layers out of Tx antenna ports + + // pmi=1,...,pmi_size, we construct + for (int ll = 0; ll < N1 * O1; ll++) { // i_1_1 + for (int mm = 0; mm < N2 * O2; mm++) { // i_1_2 + for (int k1 = 0; k1 < K1; k1++) { + for (int k2 = 0; k2 < K2; k2++) { + for (int nn = 0; nn < 2; nn++) { // i_2 + pmiq++; + pmi_pdu[pmiq].pm_idx = pmiq + 1; // index 0 is the identity matrix + pmi_pdu[pmiq].numLayers = 2; + pmi_pdu[pmiq].num_ant_ports = num_antenna_ports; + LOG_D(PHY, "layer 2 Codebook pmiq = %d\n", pmiq); + for (int j_col = 0; j_col < 2; j_col++) { + if (j_col == 0) { + llc = ll; + mmc = mm; + phase_sign = 1; + } + if (j_col == 1) { + llc = ll + k1 * O1; + mmc = mm + k2 * O2; + phase_sign = -1; + } + for (int i_rows = 0; i_rows < N1 * N2; i_rows++) { + nfapi_nr_pm_weights_t *weights = &pmi_pdu[pmiq].weights[j_col][i_rows]; + res_code = sqrt(1 / (double)(2 * num_antenna_ports)) * v_lm[llc][mmc][i_rows]; + c16_t precoder_weight = convert_precoder_weight(res_code); + weights->precoder_weight_Re = precoder_weight.r; + weights->precoder_weight_Im = precoder_weight.i; + LOG_D(PHY, + "2 Layer Precoding Matrix[1][pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d \n", + pmiq, + i_rows, + j_col, + creal(res_code), + cimag(res_code), + weights->precoder_weight_Re, + weights->precoder_weight_Im); + } + for (int i_rows = N1 * N2; i_rows < 2 * N1 * N2; i_rows++) { + nfapi_nr_pm_weights_t *weights = &pmi_pdu[pmiq].weights[j_col][i_rows]; + res_code = sqrt(1 / (double)(2 * num_antenna_ports)) * (phase_sign)*theta_n[nn] * v_lm[llc][mmc][i_rows - N1 * N2]; + c16_t precoder_weight = convert_precoder_weight(res_code); + weights->precoder_weight_Re = precoder_weight.r; + weights->precoder_weight_Im = precoder_weight.i; + LOG_D(PHY, + "2 Layer Precoding Matrix[1][pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d \n", + pmiq, + i_rows, + j_col, + creal(res_code), + cimag(res_code), + weights->precoder_weight_Re, + weights->precoder_weight_Im); + } + } + } + } + } + } + } + + if (max_mimo_layers < 3) + return mat; + + // Table 5.2.2.2.1-7: + // Codebook for 3-layer CSI reporting using antenna ports 3000 to 2999+PCSI-RS + + // pmi=1,...,pmi_size are computed as follows + for (int ll = 0; ll < N1 * O1; ll++) { // i_1_1 + for (int mm = 0; mm < N2 * O2; mm++) { // i_1_2 + for (int k1 = 0; k1 < K1; k1++) { + for (int k2 = 0; k2 < K2; k2++) { + for (int nn = 0; nn < 2; nn++) { // i_2 + pmiq++; + pmi_pdu[pmiq].pm_idx = pmiq + 1; // index 0 is the identity matrix + pmi_pdu[pmiq].numLayers = 3; + pmi_pdu[pmiq].num_ant_ports = num_antenna_ports; + LOG_D(PHY, "layer 3 Codebook pmiq = %d\n", pmiq); + for (int j_col = 0; j_col < 3; j_col++) { + if (j_col == 0) { + llc = ll; + mmc = mm; + phase_sign = 1; + } + if (j_col == 1) { + llc = ll + k1 * O1; + mmc = mm + k2 * O2; + phase_sign = 1; + } + if (j_col == 2) { + llc = ll; + mmc = mm; + phase_sign = -1; + } + for (int i_rows = 0; i_rows < N1 * N2; i_rows++) { + nfapi_nr_pm_weights_t *weights = &pmi_pdu[pmiq].weights[j_col][i_rows]; + res_code = sqrt(1 / (double)(3 * num_antenna_ports)) * v_lm[llc][mmc][i_rows]; + c16_t precoder_weight = convert_precoder_weight(res_code); + weights->precoder_weight_Re = precoder_weight.r; + weights->precoder_weight_Im = precoder_weight.i; + LOG_D(PHY, + "3 Layer Precoding Matrix[1][pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d \n", + pmiq, + i_rows, + j_col, + creal(res_code), + cimag(res_code), + weights->precoder_weight_Re, + weights->precoder_weight_Im); + } + for (int i_rows = N1 * N2; i_rows < 2 * N1 * N2; i_rows++) { + nfapi_nr_pm_weights_t *weights = &pmi_pdu[pmiq].weights[j_col][i_rows]; + res_code = sqrt(1 / (double)(3 * num_antenna_ports)) * (phase_sign)*theta_n[nn] * v_lm[llc][mmc][i_rows - N1 * N2]; + c16_t precoder_weight = convert_precoder_weight(res_code); + weights->precoder_weight_Re = precoder_weight.r; + weights->precoder_weight_Im = precoder_weight.i; + LOG_D(PHY, + "3 Layer Precoding Matrix[1][pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d \n", + pmiq, + i_rows, + j_col, + creal(res_code), + cimag(res_code), + weights->precoder_weight_Re, + weights->precoder_weight_Im); + } + } + } + } + } + } + } + + if (max_mimo_layers < 4) + return mat; + + // Table 5.2.2.2.1-8: + // Codebook for 4-layer CSI reporting using antenna ports 3000 to 2999+PCSI-RS + + for (int ll = 0; ll < N1 * O1; ll++) { // i_1_1 + for (int mm = 0; mm < N2 * O2; mm++) { // i_1_2 + for (int k1 = 0; k1 < K1; k1++) { + for (int k2 = 0; k2 < K2; k2++) { + for (int nn = 0; nn < 2; nn++) { // i_2 + pmiq++; + pmi_pdu[pmiq].pm_idx = pmiq + 1; // index 0 is the identity matrix + pmi_pdu[pmiq].numLayers = 4; + pmi_pdu[pmiq].num_ant_ports = num_antenna_ports; + LOG_D(PHY, "layer 4 pmiq = %d\n", pmiq); + for (int j_col = 0; j_col < 4; j_col++) { + if (j_col == 0) { + llc = ll; + mmc = mm; + phase_sign = 1; + } + if (j_col == 1) { + llc = ll + k1 * O1; + mmc = mm + k2 * O2; + phase_sign = 1; + } + if (j_col == 2) { + llc = ll; + mmc = mm; + phase_sign = -1; + } + if (j_col == 3) { + llc = ll + k1 * O1; + mmc = mm + k2 * O2; + phase_sign = -1; + } + for (int i_rows = 0; i_rows < N1 * N2; i_rows++) { + nfapi_nr_pm_weights_t *weights = &pmi_pdu[pmiq].weights[j_col][i_rows]; + res_code = sqrt(1 / (double)(4 * num_antenna_ports)) * v_lm[llc][mmc][i_rows]; + c16_t precoder_weight = convert_precoder_weight(res_code); + weights->precoder_weight_Re = precoder_weight.r; + weights->precoder_weight_Im = precoder_weight.i; + LOG_D(PHY, + "4 Layer Precoding Matrix[1][pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d \n", + pmiq, + i_rows, + j_col, + creal(res_code), + cimag(res_code), + weights->precoder_weight_Re, + weights->precoder_weight_Im); + } + for (int i_rows = N1 * N2; i_rows < 2 * N1 * N2; i_rows++) { + nfapi_nr_pm_weights_t *weights = &pmi_pdu[pmiq].weights[j_col][i_rows]; + res_code = sqrt(1 / (double)(4 * num_antenna_ports)) * (phase_sign)*theta_n[nn] * v_lm[llc][mmc][i_rows - N1 * N2]; + c16_t precoder_weight = convert_precoder_weight(res_code); + weights->precoder_weight_Re = precoder_weight.r; + weights->precoder_weight_Im = precoder_weight.i; + LOG_D(PHY, + "4 Layer Precoding Matrix[1][pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d \n", + pmiq, + i_rows, + j_col, + creal(res_code), + cimag(res_code), + weights->precoder_weight_Re, + weights->precoder_weight_Im); + } + } + } + } + } + } + } + return mat; } static void process_rlcBearerConfig(struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list, diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index bac4c0ce64..161598ec2d 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -2062,29 +2062,18 @@ static void nr_fill_rar(uint8_t Mod_idP, NR_RA_t *ra, uint8_t *dlsch_buffer, nfa LOG_I(NR_MAC, "rar->TCRNTI_1 = 0x%x\n", rar->TCRNTI_1); LOG_I(NR_MAC, "rar->TCRNTI_2 = 0x%x\n", rar->TCRNTI_2); #endif - - int mcs = (unsigned char) (rar->UL_GRANT_4 >> 4); - // time alloc - int Msg3_t_alloc = (unsigned char) (rar->UL_GRANT_3 & 0x0f); - // frequency alloc - int Msg3_f_alloc = (uint16_t) ((rar->UL_GRANT_3 >> 4) | (rar->UL_GRANT_2 << 4) | ((rar->UL_GRANT_1 & 0x03) << 12)); - // frequency hopping - int freq_hopping = (unsigned char) (rar->UL_GRANT_1 >> 2); - // TA command - int ta_command = rar->TA2 + (rar->TA1 << 5); - // TC-RNTI - int t_crnti = rar->TCRNTI_2 + (rar->TCRNTI_1 << 8); - - LOG_D(NR_MAC, "In %s: Transmitted RAR with t_alloc %d f_alloc %d ta_command %d mcs %d freq_hopping %d tpc_command %d csi_req %d t_crnti %x \n", + LOG_D(NR_MAC, + "In %s: Transmitted RAR with t_alloc %d f_alloc %d ta_command %d mcs %d freq_hopping %d tpc_command %d csi_req %d t_crnti " + "%x \n", __FUNCTION__, - Msg3_t_alloc, - Msg3_f_alloc, - ta_command, - mcs, - freq_hopping, + rar->UL_GRANT_3 & 0x0f, + (rar->UL_GRANT_3 >> 4) | (rar->UL_GRANT_2 << 4) | ((rar->UL_GRANT_1 & 0x03) << 12), + rar->TA2 + (rar->TA1 << 5), + rar->UL_GRANT_4 >> 4, + rar->UL_GRANT_1 >> 2, tpc_command, csi_req, - t_crnti); + rar->TCRNTI_2 + (rar->TCRNTI_1 << 8)); } void nr_schedule_RA(module_id_t module_idP, diff --git a/openair2/UTIL/OPT/probe.c b/openair2/UTIL/OPT/probe.c index e782453e5a..58ea8764e9 100644 --- a/openair2/UTIL/OPT/probe.c +++ b/openair2/UTIL/OPT/probe.c @@ -542,8 +542,10 @@ void trace_pdu_implementation(int nr, int direction, uint8_t *pdu_buffer, unsign int init_opt(void) { paramdef_t opt_params[] = OPT_PARAMS_DESC ; checkedparam_t opt_checkParams[] = OPTPARAMS_CHECK_DESC; - config_set_checkfunctions(opt_params, opt_checkParams, sizeofArray(opt_params)); - config_get(config_get_if(), opt_params, sizeofArray(opt_params), OPT_CONFIGPREFIX); + int sz=sizeofArray(opt_params); + AssertFatal(sz == sizeofArray(opt_checkParams), "Error in arrays size (%d!=%lu)\n", sz, sizeofArray(opt_checkParams)); + config_set_checkfunctions(opt_params, opt_checkParams, sz); + config_get(config_get_if(), opt_params, sz, OPT_CONFIGPREFIX); subframesSinceCaptureStart = 0; int tmptype = config_get_processedint(config_get_if(), &(opt_params[OPTTYPE_IDX])); diff --git a/radio/BLADERF/bladerf_lib.c b/radio/BLADERF/bladerf_lib.c index 9ac15bcd1e..e834f8377e 100644 --- a/radio/BLADERF/bladerf_lib.c +++ b/radio/BLADERF/bladerf_lib.c @@ -138,7 +138,7 @@ static int trx_brf_write(openair0_device *device, brf_state_t *brf = (brf_state_t*)device->priv; /* BRF has only 1 rx/tx chaine : is it correct? */ int16_t *samples = (int16_t*)buff[0]; - + timestamp -= device->openair0_cfg->command_line_sample_advance - device->openair0_cfg->tx_sample_advance; //memset(&brf->meta_tx, 0, sizeof(brf->meta_tx)); // When BLADERF_META_FLAG_TX_NOW is used the timestamp is not used, so one can't schedule a tx if (brf->meta_tx.flags == 0 ) diff --git a/radio/COMMON/common_lib.c b/radio/COMMON/common_lib.c index 087e1bc5d7..a78753fbe9 100644 --- a/radio/COMMON/common_lib.c +++ b/radio/COMMON/common_lib.c @@ -96,7 +96,7 @@ int load_lib(openair0_device *device, loader_shlibfunc_t shlib_fdesc[1]; int ret=0; char *deflibname=OAI_RF_LIBNAME; - + openair0_cfg->command_line_sample_advance = get_softmodem_params()->command_line_sample_advance; openair0_cfg->recplay_mode = read_recplayconfig(&(openair0_cfg->recplay_conf),&(device->recplay_state)); if (openair0_cfg->recplay_mode == RECPLAY_RECORDMODE) { diff --git a/radio/COMMON/common_lib.h b/radio/COMMON/common_lib.h index 3ba6a381dc..ead62cb0c7 100644 --- a/radio/COMMON/common_lib.h +++ b/radio/COMMON/common_lib.h @@ -215,6 +215,7 @@ typedef struct openair0_config { int mmapped_dma; //! offset in samples between TX and RX paths int tx_sample_advance; + int command_line_sample_advance; //! samples per packet on the fronthaul interface int samples_per_packet; //! number of RX channels (=RX antennas) diff --git a/radio/IRIS/iris_lib.cpp b/radio/IRIS/iris_lib.cpp index 13cdfb6a44..47f4d2b4ef 100644 --- a/radio/IRIS/iris_lib.cpp +++ b/radio/IRIS/iris_lib.cpp @@ -137,7 +137,7 @@ trx_iris_write(openair0_device *device, openair0_timestamp timestamp, void **buf using namespace std::chrono; int flag = 0; - + timestamp -= device->openair0_cfg->command_line_sample_advance - device->openair0_cfg->tx_sample_advance; iris_state_t *s = (iris_state_t *) device->priv; int nsamps2; // aligned to upper 32 or 16 byte boundary nsamps2 = (nsamps+7)>>3; @@ -164,8 +164,7 @@ trx_iris_write(openair0_device *device, openair0_timestamp timestamp, void **buf flag |= SOAPY_SDR_END_BURST; } - - long long timeNs = SoapySDR::ticksToTimeNs(timestamp, s->sample_rate / SAMPLE_RATE_DOWN); + long long timeNs = SoapySDR::ticksToTimeNs(timestamp - device.command_line_sample_advance, s->sample_rate / SAMPLE_RATE_DOWN); uint32_t *samps[2]; //= (uint32_t **)buff; int r; int m = s->tx_num_channels; diff --git a/radio/LMSSDR/lms_lib.cpp b/radio/LMSSDR/lms_lib.cpp index df3e0c8a9b..3d0dd78118 100644 --- a/radio/LMSSDR/lms_lib.cpp +++ b/radio/LMSSDR/lms_lib.cpp @@ -73,15 +73,13 @@ int write_output(const char *fname,const char *vname,void *data,int length,int d \returns 0 on success */ int trx_lms_write(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int antenna_id, int flags) { + timestamp -= device->openair0_cfg->command_line_sample_advance - device->openair0_cfg->tx_sample_advance; + lms_stream_meta_t meta; + meta.waitForTimestamp = true; + meta.flushPartialPacket = false; + meta.timestamp = timestamp; - - lms_stream_meta_t meta; - meta.waitForTimestamp = true; - meta.flushPartialPacket = false; - meta.timestamp = timestamp; - - - return LMS_SendStream(&tx_stream,(const void*)buff[0],nsamps,&meta,30); + return LMS_SendStream(&tx_stream, (const void *)buff[0], nsamps, &meta, 30); } /*! \brief Receive samples from hardware. diff --git a/radio/USRP/usrp_lib.cpp b/radio/USRP/usrp_lib.cpp index 73fdc8032f..4218ae7748 100644 --- a/radio/USRP/usrp_lib.cpp +++ b/radio/USRP/usrp_lib.cpp @@ -428,6 +428,7 @@ static int trx_usrp_write(openair0_device *device, int flags) { int ret=0; usrp_state_t *s = (usrp_state_t *)device->priv; + timestamp -= device->openair0_cfg->command_line_sample_advance + device->openair0_cfg->tx_sample_advance; int nsamps2; // aligned to upper 32 or 16 byte boundary radio_tx_burst_flag_t flags_burst = (radio_tx_burst_flag_t) (flags & 0xf); @@ -1316,7 +1317,7 @@ extern "C" { case 46080000: s->usrp->set_master_clock_rate(46.08e6); //openair0_cfg[0].samples_per_packet = 1024; - openair0_cfg[0].tx_sample_advance = 115; + openair0_cfg[0].tx_sample_advance = 164; openair0_cfg[0].tx_bw = 40e6; openair0_cfg[0].rx_bw = 40e6; break; diff --git a/radio/rfsimulator/simulator.c b/radio/rfsimulator/simulator.c index 44b2864f8c..0196f8b1b9 100644 --- a/radio/rfsimulator/simulator.c +++ b/radio/rfsimulator/simulator.c @@ -755,6 +755,7 @@ static int rfsimulator_write_internal(rfsimulator_state_t *t, openair0_timestamp } static int rfsimulator_write(openair0_device *device, openair0_timestamp timestamp, void **samplesVoid, int nsamps, int nbAnt, int flags) { + timestamp -= device->openair0_cfg->command_line_sample_advance; return rfsimulator_write_internal(device->priv, timestamp, samplesVoid, nsamps, nbAnt, flags, false); // false = with lock // return rfsimulator_write_internal(device->priv, timestamp, samplesVoid, nsamps, nbAnt, flags, true); }