From 0ad9ab947c48988266a70594060d32d5afbb12ba Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Sun, 13 May 2018 15:53:59 -0700 Subject: [PATCH] dmrs-based OTA synchronization for RU --- openair1/PHY/LTE_ESTIMATION/defs.h | 9 ++ openair1/PHY/LTE_ESTIMATION/lte_sync_time.c | 118 ++++++++++++++++++++ openair1/PHY/LTE_TRANSPORT/drs_modulation.c | 74 ++++++------ openair1/PHY/LTE_TRANSPORT/proto.h | 18 +-- openair1/PHY/defs.h | 4 + openair1/SCHED/phy_procedures_lte_ue.c | 2 + openair1/SCHED/ru_procedures.c | 27 ++++- targets/RT/USER/lte-ru.c | 61 ++-------- targets/RT/USER/lte-softmodem.c | 3 +- targets/RT/USER/lte-softmodem.h | 4 +- 10 files changed, 220 insertions(+), 100 deletions(-) diff --git a/openair1/PHY/LTE_ESTIMATION/defs.h b/openair1/PHY/LTE_ESTIMATION/defs.h index a7b5d14701..07aad85e1a 100644 --- a/openair1/PHY/LTE_ESTIMATION/defs.h +++ b/openair1/PHY/LTE_ESTIMATION/defs.h @@ -92,6 +92,15 @@ int lte_sync_time_eNB_emul(PHY_VARS_eNB *phy_vars_eNb, uint8_t sect_id, int32_t *sync_val); + +int ru_sync_time_init(RU_t *ru); + +int ru_sync_time(RU_t *ru, + int64_t *lev, + int64_t *avg); + +void ru_sync_time_free(RU_t *ru); + /*! \brief This function performs channel estimation including frequency and temporal interpolation \param phy_vars_ue Pointer to UE PHY variables diff --git a/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c b/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c index d73d790a2b..319d310af2 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c @@ -479,6 +479,65 @@ int lte_sync_time(int **rxdata, ///rx data in time domain } + +int ru_sync_time_init(RU_t *ru) // LTE_UE_COMMON *common_vars +{ + + int16_t dmrs[2048]; + int16_t *dmrsp[2] = {dmrs,NULL}; + + ru->dmrssync = (int16_t*)malloc16_clear(ru->frame_parms.N_RB_DL*2*sizeof(int16_t)); + generate_drs_pusch(NULL,NULL, + &ru->frame_parms, + (int32_t**)dmrsp, + 0, + AMP, + 0, + 0, + ru->frame_parms.N_RB_DL, + 0); + + switch (ru->frame_parms.N_RB_DL) { + case 6: + idft128(dmrs, /// complex input + ru->dmrssync, /// complex output + 1); + break; + case 25: + idft512(dmrs, + ru->dmrssync, /// complex output + 1); + break; + case 50: + idft1024(dmrs, + ru->dmrssync, /// complex output + 1); + break; + + case 75: + idft1536(dmrs, + ru->dmrssync, + 1); /// complex output + break; + case 100: + idft2048(dmrs, + ru->dmrssync, /// complex output + 1); + break; + default: + AssertFatal(1==0,"Unsupported N_RB_DL %d\n",ru->frame_parms.N_RB_DL); + break; + } + + return(0); +} + +void ru_sync_time_free(RU_t *ru) { + + AssertFatal(ru->dmrssync!=NULL,"ru->dmrssync is NULL\n"); + free(ru->dmrssync); +} + //#define DEBUG_PHY int lte_sync_time_eNB(int32_t **rxdata, ///rx data in time domain @@ -570,3 +629,62 @@ int lte_sync_time_eNB(int32_t **rxdata, ///rx data in time domain } +int ru_sync_time(RU_t *ru, + int64_t *lev, + int64_t *avg) +{ + + + LTE_DL_FRAME_PARMS *frame_parms = &ru->frame_parms; + + // perform a time domain correlation using the oversampled sync sequence + + int length = LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti; + + + // circular copy of beginning to end of rxdata buffer. Note: buffer should be big enough upon calling this function + for (int ar=0;arnb_rx;ar++) memcpy((void*)&ru->common.rxdata[ar][2*length], + (void*)&ru->common.rxdata[ar][0], + frame_parms->ofdm_symbol_size); + + int32_t tmp0; + int32_t magtmp0,maxlev0=0; + int maxpos0=0; + int64_t avg0=0; + int32_t result; + + + for (int n=0; nnb_rx; ar++) { + + result = dot_product(ru->dmrssync, + (int16_t*) &ru->common.rxdata[ar][n], + frame_parms->ofdm_symbol_size, + 11); + ((int16_t*)&tmp0)[0] += ((int16_t*) &result)[0]; + ((int16_t*)&tmp0)[1] += ((int16_t*) &result)[1]; + } + + // tmpi holds ++...+ + + magtmp0 = abs32(tmp0); + + // this does max |tmp0(n)|^2 and argmax |tmp0(n)|^2 + + if (magtmp0>maxlev0) { maxlev0 = magtmp0; maxpos0 = n; } + avg0 += magtmp0; + } + avg0/=(length/4); + + int dmrsoffset = 2*(frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples) + frame_parms->nb_prefix_samples0; + + if ((int64_t)maxlev0 > (5*avg0)) {*lev = maxlev0; *avg=avg0; return((length+maxpos0-dmrsoffset)%length);} + + return(-1); + + +} diff --git a/openair1/PHY/LTE_TRANSPORT/drs_modulation.c b/openair1/PHY/LTE_TRANSPORT/drs_modulation.c index a0bde219b5..30a78ed0fd 100644 --- a/openair1/PHY/LTE_TRANSPORT/drs_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/drs_modulation.c @@ -36,6 +36,8 @@ int generate_drs_pusch(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, + LTE_DL_FRAME_PARMS *frame_parms, + int32_t **txdataF, uint8_t eNB_id, short amp, unsigned int subframe, @@ -54,29 +56,33 @@ int generate_drs_pusch(PHY_VARS_UE *ue, int16_t alpha_re[12] = {32767, 28377, 16383, 0,-16384, -28378,-32768,-28378,-16384, -1, 16383, 28377}; int16_t alpha_im[12] = {0, 16383, 28377, 32767, 28377, 16383, 0,-16384,-28378,-32768,-28378,-16384}; - uint8_t cyclic_shift,cyclic_shift0,cyclic_shift1; - LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; - int32_t *txdataF = ue->common_vars.txdataF[ant]; + uint8_t cyclic_shift,cyclic_shift0=0,cyclic_shift1=0; + LTE_DL_FRAME_PARMS *fp = (ue==NULL) ? frame_parms : &ue->frame_parms; + int32_t *txF = (ue==NULL) ? txdataF[ant] : ue->common_vars.txdataF[ant]; uint32_t u,v,alpha_ind; - uint32_t u0=frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.grouphop[subframe<<1]; - uint32_t u1=frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.grouphop[1+(subframe<<1)]; - uint32_t v0=frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[subframe<<1]; - uint32_t v1=frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[1+(subframe<<1)]; + uint32_t u0=0,u1=0,v0=0,v1=0; int32_t ref_re,ref_im; - uint8_t harq_pid = subframe2harq_pid(frame_parms,proc->frame_tx,subframe); + uint8_t harq_pid = (proc == NULL) ? 0: subframe2harq_pid(fp,proc->frame_tx,subframe); - cyclic_shift0 = (frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift + - ue->ulsch[eNB_id]->harq_processes[harq_pid]->n_DMRS2 + - frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.nPRS[subframe<<1]+ - ((ue->ulsch[0]->cooperation_flag==2)?10:0)+ - ant*6) % 12; - // printf("PUSCH.cyclicShift %d, n_DMRS2 %d, nPRS %d\n",frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift,ue->ulsch[eNB_id]->n_DMRS2,ue->lte_frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.nPRS[subframe<<1]); - cyclic_shift1 = (frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift + - ue->ulsch[eNB_id]->harq_processes[harq_pid]->n_DMRS2 + - frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.nPRS[(subframe<<1)+1]+ - ((ue->ulsch[0]->cooperation_flag==2)?10:0)+ - ant*6) % 12; + if (ue!=NULL) { + cyclic_shift0 = (fp->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift + + ue->ulsch[eNB_id]->harq_processes[harq_pid]->n_DMRS2 + + fp->pusch_config_common.ul_ReferenceSignalsPUSCH.nPRS[subframe<<1]+ + ((ue->ulsch[0]->cooperation_flag==2)?10:0)+ + ant*6) % 12; + // printf("PUSCH.cyclicShift %d, n_DMRS2 %d, nPRS %d\n",frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift,ue->ulsch[eNB_id]->n_DMRS2,ue->lte_frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.nPRS[subframe<<1]); + cyclic_shift1 = (fp->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift + + ue->ulsch[eNB_id]->harq_processes[harq_pid]->n_DMRS2 + + fp->pusch_config_common.ul_ReferenceSignalsPUSCH.nPRS[(subframe<<1)+1]+ + ((ue->ulsch[0]->cooperation_flag==2)?10:0)+ + ant*6) % 12; + u0=fp->pusch_config_common.ul_ReferenceSignalsPUSCH.grouphop[subframe<<1]; + u1=fp->pusch_config_common.ul_ReferenceSignalsPUSCH.grouphop[1+(subframe<<1)]; + v0=fp->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[subframe<<1]; + v1=fp->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[1+(subframe<<1)]; + } + // cyclic_shift0 = 0; // cyclic_shift1 = 0; Msc_RS = 12*nb_rb; @@ -90,9 +96,9 @@ int generate_drs_pusch(PHY_VARS_UE *ue, return(-1); } - for (l = (3 - frame_parms->Ncp),u=u0,v=v0,cyclic_shift=cyclic_shift0; + for (l = (3 - fp->Ncp),u=u0,v=v0,cyclic_shift=cyclic_shift0; lsymbols_per_tti; - l += (7 - frame_parms->Ncp),u=u1,v=v1,cyclic_shift=cyclic_shift1) { + l += (7 - fp->Ncp),u=u1,v=v1,cyclic_shift=cyclic_shift1) { drs_offset = 0; #ifdef DEBUG_DRS @@ -100,9 +106,9 @@ int generate_drs_pusch(PHY_VARS_UE *ue, #endif - re_offset = frame_parms->first_carrier_offset; - subframe_offset = subframe*frame_parms->symbols_per_tti*frame_parms->ofdm_symbol_size; - symbol_offset = subframe_offset + frame_parms->ofdm_symbol_size*l; + re_offset = fp->first_carrier_offset; + subframe_offset = subframe*fp->symbols_per_tti*frame_parms->ofdm_symbol_size; + symbol_offset = subframe_offset + fp->ofdm_symbol_size*l; #ifdef DEBUG_DRS @@ -110,7 +116,7 @@ int generate_drs_pusch(PHY_VARS_UE *ue, #endif alpha_ind = 0; - for (rb=0; rbN_RB_UL; rb++) { + for (rb=0; rbN_RB_UL; rb++) { if ((rb >= first_rb) && (rb<(first_rb+nb_rb))) { @@ -122,12 +128,12 @@ int generate_drs_pusch(PHY_VARS_UE *ue, ref_re = (int32_t) ul_ref_sigs[u][v][Msc_RS_idx][drs_offset<<1]; ref_im = (int32_t) ul_ref_sigs[u][v][Msc_RS_idx][(drs_offset<<1)+1]; - ((int16_t*) txdataF)[2*(symbol_offset + re_offset)] = (int16_t) (((ref_re*alpha_re[alpha_ind]) - + ((int16_t*) txF)[2*(symbol_offset + re_offset)] = (int16_t) (((ref_re*alpha_re[alpha_ind]) - (ref_im*alpha_im[alpha_ind]))>>15); - ((int16_t*) txdataF)[2*(symbol_offset + re_offset)+1] = (int16_t) (((ref_re*alpha_im[alpha_ind]) + + ((int16_t*) txF)[2*(symbol_offset + re_offset)+1] = (int16_t) (((ref_re*alpha_im[alpha_ind]) + (ref_im*alpha_re[alpha_ind]))>>15); - ((short*) txdataF)[2*(symbol_offset + re_offset)] = (short) ((((short*) txdataF)[2*(symbol_offset + re_offset)]*(int32_t)amp)>>15); - ((short*) txdataF)[2*(symbol_offset + re_offset)+1] = (short) ((((short*) txdataF)[2*(symbol_offset + re_offset)+1]*(int32_t)amp)>>15); + ((short*) txF)[2*(symbol_offset + re_offset)] = (short) ((((short*) txF)[2*(symbol_offset + re_offset)]*(int32_t)amp)>>15); + ((short*) txF)[2*(symbol_offset + re_offset)+1] = (short) ((((short*) txF)[2*(symbol_offset + re_offset)+1]*(int32_t)amp)>>15); alpha_ind = (alpha_ind + cyclic_shift); @@ -140,14 +146,14 @@ int generate_drs_pusch(PHY_VARS_UE *ue, symbol_offset, alpha_ind, re_offset, - ((short*) txdataF)[2*(symbol_offset + re_offset)], - ((short*) txdataF)[2*(symbol_offset + re_offset)+1]); + ((short*) txF)[2*(symbol_offset + re_offset)], + ((short*) txF)[2*(symbol_offset + re_offset)+1]); #endif // DEBUG_DRS re_offset++; drs_offset++; - if (re_offset >= frame_parms->ofdm_symbol_size) + if (re_offset >= fp->ofdm_symbol_size) re_offset = 0; } @@ -156,8 +162,8 @@ int generate_drs_pusch(PHY_VARS_UE *ue, // check if we crossed the symbol boundary and skip DC - if (re_offset >= frame_parms->ofdm_symbol_size) { - if (frame_parms->N_RB_DL&1) // odd number of RBs + if (re_offset >= fp->ofdm_symbol_size) { + if (fp->N_RB_DL&1) // odd number of RBs re_offset=6; else // even number of RBs (doesn't straddle DC) re_offset=0; diff --git a/openair1/PHY/LTE_TRANSPORT/proto.h b/openair1/PHY/LTE_TRANSPORT/proto.h index 0e1a60c0b9..2915918583 100644 --- a/openair1/PHY/LTE_TRANSPORT/proto.h +++ b/openair1/PHY/LTE_TRANSPORT/proto.h @@ -1660,15 +1660,17 @@ int32_t generate_srs_tx(PHY_VARS_UE *phy_vars_ue, /*! \brief This function generates the downlink reference signal for the PUSCH according to 36.211 v8.6.0. The DRS occuies the RS defined by rb_alloc and the symbols 2 and 8 for extended CP and 3 and 10 for normal CP. */ +int generate_drs_pusch(PHY_VARS_UE *ue, + UE_rxtx_proc_t *proc, + LTE_DL_FRAME_PARMS *frame_parms, + int32_t **txdataF, + uint8_t eNB_id, + short amp, + unsigned int subframe, + unsigned int first_rb, + unsigned int nb_rb, + uint8_t ant); -int32_t generate_drs_pusch(PHY_VARS_UE *phy_vars_ue, - UE_rxtx_proc_t *proc, - uint8_t eNB_id, - int16_t amp, - uint32_t subframe, - uint32_t first_rb, - uint32_t nb_rb, - uint8_t ant); /*! \brief This function initializes the Group Hopping, Sequence Hopping and nPRS sequences for PUCCH/PUSCH according to 36.211 v8.6.0. It should be called after configuration of UE (reception of SIB2/3) and initial configuration of eNB (or after reconfiguration of cell-specific parameters). diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs.h index 811517dff5..73dfe65794 100644 --- a/openair1/PHY/defs.h +++ b/openair1/PHY/defs.h @@ -717,6 +717,8 @@ typedef struct RU_t_s{ int rx_offset; /// flag to indicate the RU is a slave to another source int is_slave; + /// flag to indicate that the RU should generate the DMRS sequence in slot 2 (subframe 1) for OTA synchronization and calibration + int generate_dmrs_sync; /// flag to indicate if the RU has a control channel int has_ctrl_prt; /// counter to delay start of processing of RU until HW settles @@ -830,6 +832,8 @@ typedef struct RU_t_s{ RU_proc_t proc; /// stats thread pthread descriptor pthread_t ru_stats_thread; + /// OTA synchronization signal + int16_t *dmrssync; } RU_t; diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index 6f8f7f0579..562a15899d 100644 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -1851,6 +1851,8 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB for (aa=0; aa<1/*frame_parms->nb_antennas_tx*/; aa++) generate_drs_pusch(ue, proc, + (LTE_DL_FRAME_PARMS *)NULL, + (int32_t**)NULL, eNB_id, tx_amp, subframe_tx, diff --git a/openair1/SCHED/ru_procedures.c b/openair1/SCHED/ru_procedures.c index 534023632c..3fed116125 100644 --- a/openair1/SCHED/ru_procedures.c +++ b/openair1/SCHED/ru_procedures.c @@ -84,11 +84,28 @@ void feptx0(RU_t *ru,int slot) { 6, fp->nb_prefix_samples, CYCLIC_PREFIX); - else normal_prefix_mod(&ru->common.txdataF_BF[aa][slot*slot_sizeF], - (int*)&ru->common.txdata[aa][slot_offset], - 7, - fp); - + else { + AssertFatal(ru->generate_dmrs_sync==1 && (fp->frame_type != TDD || ru->is_slave == 1), + "ru->generate_dmrs_sync should not be set, frame_type %d, is_slave %d\n", + fp->frame_type,ru->is_slave); + + if (ru->generate_dmrs_sync == 1 && slot == 0 && subframe == 1 && aa==0) { + generate_drs_pusch((PHY_VARS_UE *)NULL, + (UE_rxtx_proc_t*)NULL, + fp, + ru->common.txdataF_BF, + 0, + AMP, + 1, + 0, + fp->N_RB_DL, + aa); + } + normal_prefix_mod(&ru->common.txdataF_BF[aa][slot*slot_sizeF], + (int*)&ru->common.txdata[aa][slot_offset], + 7, + fp); + } /* len = fp->samples_per_tti>>1; diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index be3fdfa9f1..a60588b2fd 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -123,7 +123,7 @@ extern volatile int oai_exit; extern void phy_init_RU(RU_t*); extern void phy_free_RU(RU_t*); -void init_RU(char*,clock_source_t clock_source,clock_source_t time_source); +void init_RU(char*,clock_source_t clock_source,clock_source_t time_source,int generate_dmrssync); void stop_RU(int nb_ru); void do_ru_sync(RU_t *ru); @@ -2042,8 +2042,8 @@ void *ru_thread_synch(void *arg) { RU_t *ru = (RU_t*)arg; LTE_DL_FRAME_PARMS *fp=&ru->frame_parms; int32_t sync_pos,sync_pos2; - uint32_t peak_val; - uint32_t sync_corr[307200] __attribute__((aligned(32))); + int64_t peak_val; + int64_t avg; static int ru_thread_synch_status=0; int cnt=0; @@ -2052,7 +2052,7 @@ void *ru_thread_synch(void *arg) { wait_sync("ru_thread_synch"); // initialize variables for PSS detection - lte_sync_time_init(&ru->frame_parms); + ru_sync_time_init(ru); while (!oai_exit) { @@ -2064,63 +2064,22 @@ void *ru_thread_synch(void *arg) { // run intial synch like UE LOG_I(PHY,"Running initial synchronization\n"); - sync_pos = lte_sync_time_eNB(ru->common.rxdata, - fp, - fp->samples_per_tti*5, + ru->rx_offset = ru_sync_time(ru, &peak_val, - sync_corr); + &avg); LOG_I(PHY,"RU synch cnt %d: %d, val %d\n",cnt,sync_pos,peak_val); cnt++; if (sync_pos >= 0) { - if (sync_pos >= fp->nb_prefix_samples) - sync_pos2 = sync_pos - fp->nb_prefix_samples; - else - sync_pos2 = sync_pos + (fp->samples_per_tti*10) - fp->nb_prefix_samples; - int sync_pos_slot; - if (fp->frame_type == FDD) { - - // PSS is hypothesized in last symbol of first slot in Frame - sync_pos_slot = (fp->samples_per_tti>>1) - fp->ofdm_symbol_size - fp->nb_prefix_samples; - } - else { - // PSS is hypothesized in 2nd symbol of third slot in Frame (S-subframe) - sync_pos_slot = fp->samples_per_tti + - (fp->ofdm_symbol_size<<1) + - fp->nb_prefix_samples0 + - (fp->nb_prefix_samples); - } - if (sync_pos2 >= sync_pos_slot) - ru->rx_offset = sync_pos2 - sync_pos_slot; - else - ru->rx_offset = (fp->samples_per_tti*10) + sync_pos2 - sync_pos_slot; - - - LOG_I(PHY,"Estimated sync_pos %d, peak_val %d => timing offset %d\n",sync_pos,peak_val,ru->rx_offset); - - /* - if ((peak_val > 300000) && (sync_pos > 0)) { - // if (sync_pos++ > 3) { - write_output("ru_sync.m","sync",(void*)&sync_corr[0],fp->samples_per_tti*5,1,2); - write_output("ru_rx.m","rxs",(void*)ru->ru_time.rxdata[0][0],fp->samples_per_tti*10,1,1); - exit(-1); - } - */ + LOG_I(PHY,"Estimated peak_val %d dB, avg %d => timing offset %d\n",ru->rx_offset,dB_fixed(peak_val),dB_fixed(ru->rx_offset)); ru->in_synch = 1; } // symc_pos > 0 - else { - if (cnt>1000) { - write_output("ru_sync.m","sync",(void*)&sync_corr[0],fp->samples_per_tti*5,1,2); - write_output("ru_rx.m","rxs",(void*)ru->common.rxdata[0],fp->samples_per_tti*10,1,1); - exit(1); - } - } + else AssertFatal(cnt<1000,"Cannot find synch reference\n"); } // ru->in_synch==0 - if (release_thread(&ru->proc.mutex_synch,&ru->proc.instance_cnt_synch,"ru_synch_thread") < 0) break; } // oai_exit - lte_sync_time_free(); + ru_sync_time_free(ru); ru_thread_synch_status = 0; return &ru_thread_synch_status; @@ -2735,7 +2694,7 @@ void set_function_spec_param(RU_t *ru) extern void RCconfig_RU(void); -void init_RU(char *rf_config_file, clock_source_t clock_source,clock_source_t time_source) { +void init_RU(char *rf_config_file, clock_source_t clock_source,clock_source_t time_source,int send_dmrssync) { int ru_id; RU_t *ru; diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 179d6ccb0d..02a51da218 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -134,6 +134,7 @@ volatile int oai_exit = 0; static clock_source_t clock_source = internal,time_source=internal; static int wait_for_sync = 0; +static int send_dmrssync = 0; unsigned int mmapped_dma=0; int single_thread_flag=1; @@ -1167,7 +1168,7 @@ int main( int argc, char **argv ) printf("About to Init RU threads RC.nb_RU:%d\n", RC.nb_RU); if (RC.nb_RU >0) { printf("Initializing RU threads\n"); - init_RU(rf_config_file,clock_source,time_source); + init_RU(rf_config_file,clock_source,time_source,send_dmrssync); for (ru_id=0;ru_idrf_map.card=0; RC.ru[ru_id]->rf_map.chain=CC_id+chain_offset; diff --git a/targets/RT/USER/lte-softmodem.h b/targets/RT/USER/lte-softmodem.h index 1b02cbdc6a..3b96255c6d 100644 --- a/targets/RT/USER/lte-softmodem.h +++ b/targets/RT/USER/lte-softmodem.h @@ -63,6 +63,7 @@ #define CONFIG_HLP_PHYTST "test UE phy layer, mac disabled\n" #define CONFIG_HLP_DMAMAP "sets flag for improved EXMIMO UE performance\n" #define CONFIG_HLP_EXCCLK "tells hardware to use an external clock reference\n" +#define CONFIG_HLP_DMRSSYNC "tells RU to insert DMRS in subframe 1 slot 0" #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" @@ -145,6 +146,7 @@ extern int16_t dlsch_demod_shift; {"usim-test", CONFIG_HLP_USIM, PARAMFLAG_BOOL, u8ptr:&usim_test, defintval:0, TYPE_UINT8, 0}, \ {"mmapped-dma", CONFIG_HLP_DMAMAP, PARAMFLAG_BOOL, uptr:&mmapped_dma, defintval:0, TYPE_INT, 0}, \ {"external-clock", CONFIG_HLP_EXCCLK, PARAMFLAG_BOOL, uptr:&clock_source, defintval:0, TYPE_INT, 0}, \ +{"send_dmrs_sync", CONFIG_HLP_DMRSSYNC, PARAMFLAG_BOOL, uptr:&send_dmrssync, defintval:0, TYPE_INT, 0}, \ {"wait-for-sync", NULL, PARAMFLAG_BOOL, iptr:&wait_for_sync, defintval:0, TYPE_INT, 0}, \ {"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&single_thread_flag, defintval:1, TYPE_INT, 0}, \ {"threadIQ", NULL, 0, iptr:&(threads.iq), defintval:1, TYPE_INT, 0}, \ @@ -245,7 +247,7 @@ extern void stop_eNB(int); extern void kill_eNB_proc(int inst); // In lte-ru.c -extern void init_RU(const char*,clock_source_t clock_source,clock_source_t time_source); +extern void init_RU(const char*,clock_source_t clock_source,clock_source_t time_source,int send_dmrssync); extern void init_RU_proc(RU_t *ru); extern void stop_RU(int nb_ru); extern void kill_RU_proc(int inst);