From 69ccf51f96f923485a42774dca57fb0d194ee417 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 12 Mar 2019 12:07:00 +0100 Subject: [PATCH 1/5] bugfix: fix compilation T has to be generated before compiling targets SCHED_RU_LIB and SCHED_UE_LIB. --- cmake_targets/CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 95fc2cc150..70ed10ddad 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -2231,9 +2231,9 @@ if (${T_TRACER}) 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 - GTPV1U SCTP_CLIENT UDP LIB_NAS_UE LFDS LFDS7 SIMU OPENAIR0_LIB PHY_MEX - coding) + SECU_CN SCHED_LIB SCHED_RU_LIB SCHED_UE_LIB PHY L2 default_sched + remote_sched RAL CN_UTILS GTPV1U SCTP_CLIENT UDP LIB_NAS_UE LFDS + LFDS7 SIMU OPENAIR0_LIB PHY_MEX coding) if (TARGET ${i}) add_dependencies(${i} generate_T) endif() From ee5b73901954deb33cdc6e6a7914d7e9c559e84e Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 14 Mar 2019 15:13:22 +0100 Subject: [PATCH 2/5] PHY: make sf_extension a parameter This parameter is meaningful in TDD, to decide when to start DL at eNB side. Since there is a need for the PA to be operational, we need to transmit a bit before the DL subframe coming after an UL subframe. (We transmit zeros.) We used to use N_TA_offset which may be too much. Default value is now N_TA_offset/2 and can be changed in the configuration file, in the RUs section, like: RUs = ( { local_rf = "yes" nb_tx = 1 nb_rx = 1 att_tx = 0 att_rx = 0; bands = [7]; max_pdschReferenceSignalPower = -27; max_rxgain = 105; eNB_instances = [0]; sf_extension = 312; } ); N_TA_offset is 624 (for 30.72MHz). In the example above, we set sf_extension = 312, which is also the default. The value to put in the configuration file is for 30.72MHz. The value is scaled accordingly at runtime (thus only one value to set for every RB configuration, 25, 50 or 100, leading to less problems when adapting configuration files). This option is for experts and should not be changed randomly. --- openair1/PHY/defs_eNB.h | 2 ++ openair2/ENB_APP/enb_paramdef.h | 5 ++++- targets/RT/USER/lte-ru.c | 14 ++++++++++++-- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/openair1/PHY/defs_eNB.h b/openair1/PHY/defs_eNB.h index 271d54fdce..0c41328f32 100644 --- a/openair1/PHY/defs_eNB.h +++ b/openair1/PHY/defs_eNB.h @@ -312,6 +312,8 @@ typedef struct RU_t_s{ LTE_DL_FRAME_PARMS frame_parms; ///timing offset used in TDD int N_TA_offset; + /// SF extension used in TDD (unit: number of samples at 30.72MHz) (this is an expert option) + int sf_extension; /// RF device descriptor openair0_device rfdevice; /// HW configuration diff --git a/openair2/ENB_APP/enb_paramdef.h b/openair2/ENB_APP/enb_paramdef.h index b44ec9de16..edbb34461a 100644 --- a/openair2/ENB_APP/enb_paramdef.h +++ b/openair2/ENB_APP/enb_paramdef.h @@ -101,6 +101,7 @@ typedef enum { #define CONFIG_STRING_RU_NBIOTRRC_LIST "NbIoT_RRC_instances" #define CONFIG_STRING_RU_SDR_ADDRS "sdr_addrs" #define CONFIG_STRING_RU_SDR_CLK_SRC "clock_src" +#define CONFIG_STRING_RU_SF_EXTENSION "sf_extension" #define RU_LOCAL_IF_NAME_IDX 0 #define RU_LOCAL_ADDRESS_IDX 1 @@ -122,6 +123,7 @@ typedef enum { #define RU_NBIOTRRC_LIST_IDX 17 #define RU_SDR_ADDRS 18 #define RU_SDR_CLK_SRC 19 +#define RU_SF_EXTENSION_IDX 20 @@ -149,7 +151,8 @@ typedef enum { {CONFIG_STRING_RU_ATT_RX, NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ {CONFIG_STRING_RU_NBIOTRRC_LIST, NULL, 0, uptr:NULL, defintarrayval:DEFENBS, TYPE_INTARRAY, 1}, \ {CONFIG_STRING_RU_SDR_ADDRS, NULL, 0, strptr:NULL, defstrval:"type=b200", TYPE_STRING, 0}, \ -{CONFIG_STRING_RU_SDR_CLK_SRC, NULL, 0, strptr:NULL, defstrval:"internal", TYPE_STRING, 0}, \ +{CONFIG_STRING_RU_SDR_CLK_SRC, NULL, 0, strptr:NULL, defstrval:"internal", TYPE_STRING, 0}, \ +{CONFIG_STRING_RU_SF_EXTENSION, NULL, 0, uptr:NULL, defuintval:312, TYPE_UINT, 0}, \ } /*---------------------------------------------------------------------------------------------------------------------------------------*/ diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index 787e630d17..002190ec53 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -835,7 +835,7 @@ void tx_rf(RU_t *ru) { (prevSF_type == SF_UL) && (nextSF_type == SF_DL)) { flags = 2; // start of burst - sf_extension = ru->N_TA_offset; + sf_extension = ru->sf_extension; } if ((fp->frame_type == TDD) && @@ -843,7 +843,7 @@ void tx_rf(RU_t *ru) { (prevSF_type == SF_UL) && (nextSF_type == SF_UL)) { flags = 4; // start of burst and end of burst (only one DL SF between two UL) - sf_extension = ru->N_TA_offset; + sf_extension = ru->sf_extension; } #if defined(__x86_64) || defined(__i386__) @@ -1386,6 +1386,14 @@ int setup_RU_buffers(RU_t *ru) { * TODO: find a proper cleaner solution */ ru->N_TA_offset = 0; + + if (frame_parms->N_RB_DL == 100) /* no scaling to do */; + else if (frame_parms->N_RB_DL == 50) ru->sf_extension /= 2; + else if (frame_parms->N_RB_DL == 25) ru->sf_extension /= 4; + else { printf("not handled, todo\n"); exit(1); } + } else { + ru->N_TA_offset = 0; + ru->sf_extension = 0; } if (ru->openair0_cfg.mmapped_dma == 1) { @@ -2883,6 +2891,8 @@ void RCconfig_RU(void) { RC.ru[j]->max_pdschReferenceSignalPower = *(RUParamList.paramarray[j][RU_MAX_RS_EPRE_IDX].uptr);; RC.ru[j]->max_rxgain = *(RUParamList.paramarray[j][RU_MAX_RXGAIN_IDX].uptr); RC.ru[j]->num_bands = RUParamList.paramarray[j][RU_BAND_LIST_IDX].numelt; + /* sf_extension is in unit of samples for 30.72MHz here, has to be scaled later */ + RC.ru[j]->sf_extension = *(RUParamList.paramarray[j][RU_SF_EXTENSION_IDX].uptr); for (i=0; inum_bands; i++) RC.ru[j]->band[i] = RUParamList.paramarray[j][RU_BAND_LIST_IDX].iptr[i]; } //strcmp(local_rf, "yes") == 0 From 1e71749cdfd1704e446c41e9cda9f813b3768a48 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 15 Mar 2019 11:37:54 +0100 Subject: [PATCH 3/5] PHY: bugfix: use correct count of samples for TDD DL S-subframe --- targets/RT/USER/lte-ru.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index 002190ec53..5a16a2ab7a 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -826,7 +826,8 @@ void tx_rf(RU_t *ru) { int siglen=fp->samples_per_tti,flags=1; if (SF_type == SF_S) { - siglen = fp->dl_symbols_in_S_subframe*(fp->ofdm_symbol_size+fp->nb_prefix_samples0); + siglen = (fp->ofdm_symbol_size + fp->nb_prefix_samples0) + + (fp->dl_symbols_in_S_subframe - 1) * (fp->ofdm_symbol_size + fp->nb_prefix_samples); flags=3; // end of burst } From a05753dff38ff20377331b9f8a8e719393ca44bf Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 15 Mar 2019 11:40:59 +0100 Subject: [PATCH 4/5] PHY: bugfix: compute start/end of burst correctly for TDD Start of burst is to start TDD DL transmission in the driver (tested with USRP for the moment). End of burst is to stop DL transmission. Start of burst can only happen for a DL subframe when the previous subframe was an UL subframe. End of burst can only happen for an S subframe. It's impossible for a subframe to be both the start of a burst and the end of a burst. This can be checked with eg. http://niviuk.free.fr/lte_resource_grid.html (or reading the specs). --- targets/RT/USER/lte-ru.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index 5a16a2ab7a..cedd0be270 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -818,7 +818,6 @@ void tx_rf(RU_t *ru) { T_INT(0), T_BUFFER(&ru->common.txdata[0][proc->subframe_tx * fp->samples_per_tti], fp->samples_per_tti * 4)); lte_subframe_t SF_type = subframe_select(fp,proc->subframe_tx%10); lte_subframe_t prevSF_type = subframe_select(fp,(proc->subframe_tx+9)%10); - lte_subframe_t nextSF_type = subframe_select(fp,(proc->subframe_tx+1)%10); int sf_extension = 0; if ((SF_type == SF_DL) || @@ -831,22 +830,13 @@ void tx_rf(RU_t *ru) { flags=3; // end of burst } - if ((fp->frame_type == TDD) && - (SF_type == SF_DL)&& - (prevSF_type == SF_UL) && - (nextSF_type == SF_DL)) { + if (fp->frame_type == TDD && + SF_type == SF_DL && + prevSF_type == SF_UL) { flags = 2; // start of burst sf_extension = ru->sf_extension; } - if ((fp->frame_type == TDD) && - (SF_type == SF_DL)&& - (prevSF_type == SF_UL) && - (nextSF_type == SF_UL)) { - flags = 4; // start of burst and end of burst (only one DL SF between two UL) - sf_extension = ru->sf_extension; - } - #if defined(__x86_64) || defined(__i386__) #ifdef __AVX2__ sf_extension = (sf_extension)&0xfffffff8; From 275e5b3a64188ae1399bdfcd1e27e6b5ecb6641c Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 15 Mar 2019 12:14:45 +0100 Subject: [PATCH 5/5] PHY: add parameter end_of_burst_delay for TDD end_of_burst_delay is used to stop TX only "after a while". If we stop right after effective signal, with USRP B210 and B200mini, we observe a high EVM on the S subframe (on the PSS). A value of 400 (for 30.72MHz) solves this issue. This is the default. This default value can be changed in the configuration file. For example: RUs = ( { local_rf = "yes" nb_tx = 1 nb_rx = 1 att_tx = 20 att_rx = 0; bands = [7]; max_pdschReferenceSignalPower = -27; max_rxgain = 105; eNB_instances = [0]; sf_extension = 312; end_of_burst_delay = 200; } ); Here we would set a value of 200. The value to put in the configuration file is for 30.72MHz. The value is scaled accordingly at runtime (thus only one value to set for every RB configuration, 25, 50 or 100, leading to less problems when adapting configuration files). This option is for experts and should not be changed randomly. --- openair1/PHY/defs_eNB.h | 2 ++ openair2/ENB_APP/enb_paramdef.h | 3 +++ targets/RT/USER/lte-ru.c | 25 +++++++++++++++++++++---- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/openair1/PHY/defs_eNB.h b/openair1/PHY/defs_eNB.h index 0c41328f32..d3157d5e82 100644 --- a/openair1/PHY/defs_eNB.h +++ b/openair1/PHY/defs_eNB.h @@ -314,6 +314,8 @@ typedef struct RU_t_s{ int N_TA_offset; /// SF extension used in TDD (unit: number of samples at 30.72MHz) (this is an expert option) int sf_extension; + /// "end of burst delay" used in TDD (unit: number of samples at 30.72MHz) (this is an expert option) + int end_of_burst_delay; /// RF device descriptor openair0_device rfdevice; /// HW configuration diff --git a/openair2/ENB_APP/enb_paramdef.h b/openair2/ENB_APP/enb_paramdef.h index edbb34461a..b0fb97dac1 100644 --- a/openair2/ENB_APP/enb_paramdef.h +++ b/openair2/ENB_APP/enb_paramdef.h @@ -102,6 +102,7 @@ typedef enum { #define CONFIG_STRING_RU_SDR_ADDRS "sdr_addrs" #define CONFIG_STRING_RU_SDR_CLK_SRC "clock_src" #define CONFIG_STRING_RU_SF_EXTENSION "sf_extension" +#define CONFIG_STRING_RU_END_OF_BURST_DELAY "end_of_burst_delay" #define RU_LOCAL_IF_NAME_IDX 0 #define RU_LOCAL_ADDRESS_IDX 1 @@ -124,6 +125,7 @@ typedef enum { #define RU_SDR_ADDRS 18 #define RU_SDR_CLK_SRC 19 #define RU_SF_EXTENSION_IDX 20 +#define RU_END_OF_BURST_DELAY_IDX 21 @@ -153,6 +155,7 @@ typedef enum { {CONFIG_STRING_RU_SDR_ADDRS, NULL, 0, strptr:NULL, defstrval:"type=b200", TYPE_STRING, 0}, \ {CONFIG_STRING_RU_SDR_CLK_SRC, NULL, 0, strptr:NULL, defstrval:"internal", TYPE_STRING, 0}, \ {CONFIG_STRING_RU_SF_EXTENSION, NULL, 0, uptr:NULL, defuintval:312, TYPE_UINT, 0}, \ +{CONFIG_STRING_RU_END_OF_BURST_DELAY, NULL, 0, uptr:NULL, defuintval:400, TYPE_UINT, 0}, \ } /*---------------------------------------------------------------------------------------------------------------------------------------*/ diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index cedd0be270..d4c53441d6 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -825,8 +825,16 @@ void tx_rf(RU_t *ru) { int siglen=fp->samples_per_tti,flags=1; if (SF_type == SF_S) { + /* end_of_burst_delay is used to stop TX only "after a while". + * If we stop right after effective signal, with USRP B210 and + * B200mini, we observe a high EVM on the S subframe (on the + * PSS). + * A value of 400 (for 30.72MHz) solves this issue. This is + * the default. + */ siglen = (fp->ofdm_symbol_size + fp->nb_prefix_samples0) - + (fp->dl_symbols_in_S_subframe - 1) * (fp->ofdm_symbol_size + fp->nb_prefix_samples); + + (fp->dl_symbols_in_S_subframe - 1) * (fp->ofdm_symbol_size + fp->nb_prefix_samples) + + ru->end_of_burst_delay; flags=3; // end of burst } @@ -1379,12 +1387,20 @@ int setup_RU_buffers(RU_t *ru) { ru->N_TA_offset = 0; if (frame_parms->N_RB_DL == 100) /* no scaling to do */; - else if (frame_parms->N_RB_DL == 50) ru->sf_extension /= 2; - else if (frame_parms->N_RB_DL == 25) ru->sf_extension /= 4; - else { printf("not handled, todo\n"); exit(1); } + else if (frame_parms->N_RB_DL == 50) { + ru->sf_extension /= 2; + ru->end_of_burst_delay /= 2; + } else if (frame_parms->N_RB_DL == 25) { + ru->sf_extension /= 4; + ru->end_of_burst_delay /= 4; + } else { + printf("not handled, todo\n"); + exit(1); + } } else { ru->N_TA_offset = 0; ru->sf_extension = 0; + ru->end_of_burst_delay = 0; } if (ru->openair0_cfg.mmapped_dma == 1) { @@ -2884,6 +2900,7 @@ void RCconfig_RU(void) { RC.ru[j]->num_bands = RUParamList.paramarray[j][RU_BAND_LIST_IDX].numelt; /* sf_extension is in unit of samples for 30.72MHz here, has to be scaled later */ RC.ru[j]->sf_extension = *(RUParamList.paramarray[j][RU_SF_EXTENSION_IDX].uptr); + RC.ru[j]->end_of_burst_delay = *(RUParamList.paramarray[j][RU_END_OF_BURST_DELAY_IDX].uptr); for (i=0; inum_bands; i++) RC.ru[j]->band[i] = RUParamList.paramarray[j][RU_BAND_LIST_IDX].iptr[i]; } //strcmp(local_rf, "yes") == 0