From d8c35774aa0666742ea089eb6a68c78ea7f46036 Mon Sep 17 00:00:00 2001 From: Raymond Knoppp <raymond.knopp@eurecom.fr> Date: Tue, 27 Nov 2018 12:30:10 +0100 Subject: [PATCH] modifications at slave RRU --- openair1/PHY/INIT/lte_init_ru.c | 43 +- .../PHY/LTE_ESTIMATION/lte_adjust_sync_eNB.c | 14 +- openair1/PHY/LTE_ESTIMATION/lte_estimation.h | 13 + openair1/PHY/LTE_ESTIMATION/lte_sync_time.c | 18 +- .../lte_ul_channel_estimation.c | 374 +++++++++++++++++- openair1/PHY/MODULATION/ul_7_5_kHz.c | 13 +- openair1/PHY/defs_eNB.h | 9 +- openair1/PHY/impl_defs_lte.h | 17 +- openair1/SCHED/ru_procedures.c | 85 +++- targets/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c | 2 +- targets/RT/USER/lte-ru.c | 53 ++- 11 files changed, 601 insertions(+), 40 deletions(-) diff --git a/openair1/PHY/INIT/lte_init_ru.c b/openair1/PHY/INIT/lte_init_ru.c index 17435c1af2..b1c57e052f 100644 --- a/openair1/PHY/INIT/lte_init_ru.c +++ b/openair1/PHY/INIT/lte_init_ru.c @@ -36,26 +36,38 @@ void init_7_5KHz(void); int phy_init_RU(RU_t *ru) { LTE_DL_FRAME_PARMS *fp = &ru->frame_parms; + RU_CALIBRATION *calibration = &ru->calibration; int i,j; int p; int re; LOG_I(PHY,"Initializing RU signal buffers (if_south %s) nb_tx %d\n",ru_if_types[ru->if_south],ru->nb_tx); + if (ru->is_slave == 1) { + generate_ul_ref_sigs_rx(); + init_dfts(); + } + if (ru->if_south <= REMOTE_IF5) { // this means REMOTE_IF5 or LOCAL_RF, so allocate memory for time-domain signals // Time-domain signals ru->common.txdata = (int32_t**)malloc16(ru->nb_tx*sizeof(int32_t*)); ru->common.rxdata = (int32_t**)malloc16(ru->nb_rx*sizeof(int32_t*) ); - for (i=0; i<ru->nb_tx; i++) { // Allocate 10 subframes of I/Q TX signal data (time) if not ru->common.txdata[i] = (int32_t*)malloc16_clear( fp->samples_per_tti*10*sizeof(int32_t) ); - LOG_I(PHY,"[INIT] common.txdata[%d] = %p (%lu bytes)\n",i,ru->common.txdata[i], fp->samples_per_tti*10*sizeof(int32_t)); + } + if (ru->is_slave == 1) { + calibration->drs_ch_estimates_time = (int32_t**)malloc16_clear(ru->nb_rx*sizeof(int32_t*)); + for (i=0; i<ru->nb_rx; i++) { + calibration->drs_ch_estimates_time[i] = (int32_t*)malloc16_clear(2*sizeof(int32_t)*fp->ofdm_symbol_size); + } } + + for (i=0;i<ru->nb_rx;i++) { ru->common.rxdata[i] = (int32_t*)malloc16_clear( fp->samples_per_tti*10*sizeof(int32_t) ); } @@ -91,6 +103,18 @@ int phy_init_RU(RU_t *ru) { ru->common.rxdataF[i] = (int32_t*)malloc16_clear(sizeof(int32_t)*(2*fp->ofdm_symbol_size*fp->symbols_per_tti) ); LOG_I(PHY,"rxdataF[%d] %p for RU %d\n",i,ru->common.rxdataF[i],ru->idx); } + + if (ru->is_slave == 1) { + // allocate FFT output buffers after extraction (RX) + calibration->rxdataF_ext = (int32_t**)malloc16(2*sizeof(int32_t*)); + calibration->drs_ch_estimates = (int32_t**)malloc16(2*sizeof(int32_t*)); + for (i=0; i<ru->nb_rx; i++) { + // allocate 2 subframes of I/Q signal data (frequency) + calibration->rxdataF_ext[i] = (int32_t*)malloc16_clear(sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti ); + LOG_I(PHY,"rxdataF_ext[%d] %p for RU %d\n",i,calibration->rxdataF_ext[i],ru->idx); + calibration->drs_ch_estimates[i] = (int32_t*)malloc16_clear(sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti); + } + } /* number of elements of an array X is computed as sizeof(X) / sizeof(X[0]) */ //AssertFatal(ru->nb_rx <= sizeof(ru->prach_rxsigF) / sizeof(ru->prach_rxsigF[0]), @@ -162,12 +186,19 @@ void phy_free_RU(RU_t *ru) { int i,j; int p; + RU_CALIBRATION *calibration = &ru->calibration; LOG_I(PHY, "Feeing RU signal buffers (if_south %s) nb_tx %d\n", ru_if_types[ru->if_south], ru->nb_tx); if (ru->if_south <= REMOTE_IF5) { // this means REMOTE_IF5 or LOCAL_RF, so free memory for time-domain signals for (i = 0; i < ru->nb_tx; i++) free_and_zero(ru->common.txdata[i]); for (i = 0; i < ru->nb_rx; i++) free_and_zero(ru->common.rxdata[i]); + if (ru->is_slave == 1) { + for (i = 0; i < ru->nb_rx; i++) { + free_and_zero(calibration->drs_ch_estimates_time[i]); + } + free_and_zero(calibration->drs_ch_estimates_time); + } free_and_zero(ru->common.txdata); free_and_zero(ru->common.rxdata); } // else: IF5 or local RF -> nothing to free() @@ -183,6 +214,14 @@ void phy_free_RU(RU_t *ru) // free FFT output buffers (RX) for (i = 0; i < ru->nb_rx; i++) free_and_zero(ru->common.rxdataF[i]); free_and_zero(ru->common.rxdataF); + if (ru->is_slave == 1) { + for (i = 0; i < ru->nb_rx; i++) { + free_and_zero(calibration->rxdataF_ext[i]); + free_and_zero(calibration->drs_ch_estimates[i]); + } + free_and_zero(calibration->rxdataF_ext); + free_and_zero(calibration->drs_ch_estimates); + } for (i = 0; i < ru->nb_rx; i++) { free_and_zero(ru->prach_rxsigF[i]); diff --git a/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync_eNB.c b/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync_eNB.c index 61ce019577..07f417ad98 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync_eNB.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync_eNB.c @@ -112,17 +112,23 @@ int lte_est_timing_advance(LTE_DL_FRAME_PARMS *frame_parms, } -int lte_est_timing_advance_pusch(PHY_VARS_eNB* eNB,module_id_t UE_id) +int lte_est_timing_advance_pusch(PHY_VARS_eNB *eNB,module_id_t UE_id) { int temp, i, aa, max_pos=0, max_val=0; short Re,Im; - LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms; + RU_t *ru; + ru = RC.ru[UE_id]; + //LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms; + LTE_DL_FRAME_PARMS *frame_parms = (eNB==NULL) ? &ru->frame_parms : &eNB->frame_parms; LTE_eNB_PUSCH *eNB_pusch_vars = eNB->pusch_vars[UE_id]; - int32_t **ul_ch_estimates_time= eNB_pusch_vars->drs_ch_estimates_time; + RU_CALIBRATION *calibration = &ru->calibration; + //int32_t **ul_ch_estimates_time= eNB_pusch_vars->drs_ch_estimates_time; + int32_t **ul_ch_estimates_time = calibration->drs_ch_estimates_time; + //int32_t **ul_ch_estimates_time = (eNB==NULL) ? calibration->drs_ch_estimates_time : eNB_pusch_vars->drs_ch_estimates_time; uint8_t cyclic_shift = 0; int sync_pos = (frame_parms->ofdm_symbol_size-cyclic_shift*frame_parms->ofdm_symbol_size/12)%(frame_parms->ofdm_symbol_size); - + AssertFatal(frame_parms->ofdm_symbol_size > 127,"frame_parms->ofdm_symbol_size %d<128\n",frame_parms->ofdm_symbol_size); AssertFatal(frame_parms->nb_antennas_rx >0 && frame_parms->nb_antennas_rx<3,"frame_parms->nb_antennas_rx %d not in [0,1]\n", frame_parms->nb_antennas_rx); diff --git a/openair1/PHY/LTE_ESTIMATION/lte_estimation.h b/openair1/PHY/LTE_ESTIMATION/lte_estimation.h index 013b718e04..53d874a8fc 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_estimation.h +++ b/openair1/PHY/LTE_ESTIMATION/lte_estimation.h @@ -217,6 +217,19 @@ int lte_ul_channel_estimation(PHY_VARS_eNB *phy_vars_eNB, uint8_t l, uint8_t Ns); +int32_t lte_ul_channel_estimation_RRU(LTE_DL_FRAME_PARMS *frame_parms, + int32_t **ul_ch_estimates, + int32_t **ul_ch_estimates_time, + int32_t **rxdataF_ext, + int N_rb_alloc, + int frame_rx, + int subframe_rx, + uint32_t u, + uint32_t v, + uint32_t cyclic_shift, + unsigned char l, + int interpolate, + uint16_t rnti); int16_t lte_ul_freq_offset_estimation(LTE_DL_FRAME_PARMS *frame_parms, int32_t *ul_ch_estimates, diff --git a/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c b/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c index 1a0e8bdebe..d796cd7ebb 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c @@ -648,6 +648,7 @@ int ru_sync_time(RU_t *ru, LTE_DL_FRAME_PARMS *frame_parms = &ru->frame_parms; + RU_CALIBRATION *calibration = &ru->calibration; // perform a time domain correlation using the oversampled sync sequence @@ -671,6 +672,14 @@ int ru_sync_time(RU_t *ru, maxval = max(maxval,ru->dmrssync[i]); maxval = max(maxval,-ru->dmrssync[i]); } + + if (ru->state == RU_CHECK_SYNC) { + for (int i=0;i<2*(frame_parms->ofdm_symbol_size);i++) { + maxval = max(maxval,calibration->drs_ch_estimates_time[0][i]); + maxval = max(maxval,-calibration->drs_ch_estimates_time[0][i]); + } + } + int shift = log2_approx(maxval); for (int n=0; n<length; n+=4) { @@ -684,6 +693,13 @@ int ru_sync_time(RU_t *ru, (int16_t*) &ru->common.rxdata[ar][n], frame_parms->ofdm_symbol_size, shift); + + if (ru->state == RU_CHECK_SYNC) { + result = dot_product64((int16_t*) &calibration->drs_ch_estimates_time[ar], + (int16_t*) &ru->common.rxdata[ar][n], + frame_parms->ofdm_symbol_size, + shift); + } dmrs_corr += abs64(result); } if (ru->dmrs_corr != NULL) ru->dmrs_corr[n] = dmrs_corr; @@ -696,7 +712,7 @@ int ru_sync_time(RU_t *ru, } avg0/=(length/4); - int dmrsoffset = frame_parms->samples_per_tti + (3*frame_parms->ofdm_symbol_size)+(2*frame_parms->nb_prefix_samples) + frame_parms->nb_prefix_samples0; + int dmrsoffset = frame_parms->samples_per_tti + (3*frame_parms->ofdm_symbol_size)+(3*frame_parms->nb_prefix_samples) + frame_parms->nb_prefix_samples0; if ((int64_t)maxlev0 > (10*avg0)) {*lev = maxlev0; *avg=avg0; return((length+maxpos0-dmrsoffset)%length);} diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c index 206ba8b15f..44d8832e7a 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c @@ -39,14 +39,26 @@ int32_t lte_ul_channel_estimation(PHY_VARS_eNB *eNB, module_id_t UE_id, unsigned char l, unsigned char Ns) { - - LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms; + RU_t *ru; + ru = RC.ru[UE_id]; + LTE_DL_FRAME_PARMS *frame_parms = (eNB==NULL) ? &eNB->frame_parms : &ru->frame_parms; + //LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms; LTE_eNB_PUSCH *pusch_vars = eNB->pusch_vars[UE_id]; - int32_t **ul_ch_estimates=pusch_vars->drs_ch_estimates; - int32_t **ul_ch_estimates_time= pusch_vars->drs_ch_estimates_time; - int32_t **rxdataF_ext= pusch_vars->rxdataF_ext; - int subframe = proc->subframe_rx; + RU_CALIBRATION *calibration = &ru->calibration; + //int32_t **ul_ch_estimates=pusch_vars->drs_ch_estimates; + int32_t **ul_ch_estimates = (eNB==NULL) ? pusch_vars->drs_ch_estimates : calibration->drs_ch_estimates; + + //int32_t **ul_ch_estimates_time= pusch_vars->drs_ch_estimates_time; + int32_t **ul_ch_estimates_time = (eNB==NULL) ? pusch_vars->drs_ch_estimates_time : calibration->drs_ch_estimates_time; + + //int32_t **rxdataF_ext= pusch_vars->rxdataF_ext; + int32_t **rxdataF_ext = (eNB==NULL) ? pusch_vars->rxdataF_ext : calibration->rxdataF_ext; + + int subframe = (eNB==NULL) ? proc->subframe_rx : ru->proc.subframe_rx; + //int subframe = proc->subframe_rx; + uint8_t harq_pid = subframe2harq_pid(frame_parms,proc->frame_rx,subframe); + int16_t delta_phase = 0; int16_t *ru1 = ru_90; int16_t *ru2 = ru_90; @@ -413,6 +425,356 @@ int32_t temp_in_ifft_0[2048*2] __attribute__((aligned(32))); return(0); } +int32_t lte_ul_channel_estimation_RRU(LTE_DL_FRAME_PARMS *frame_parms, + int32_t **ul_ch_estimates, + int32_t **ul_ch_estimates_time, + int32_t **rxdataF_ext, + int N_rb_alloc, + int frame_rx, + int subframe_rx, + uint32_t u, + uint32_t v, + uint32_t cyclic_shift, + unsigned char l, + int interpolate, + uint16_t rnti) { + + int16_t delta_phase = 0; + int16_t *ru1 = ru_90; + int16_t *ru2 = ru_90; + int16_t current_phase1,current_phase2; + uint16_t aa,Msc_RS,Msc_RS_idx; + uint16_t * Msc_idx_ptr; + int k,pilot_pos1 = 3 - frame_parms->Ncp, pilot_pos2 = 10 - 2*frame_parms->Ncp; + int32_t *ul_ch1=NULL, *ul_ch2=NULL; + int16_t ul_ch_estimates_re,ul_ch_estimates_im; + uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx; + uint32_t alpha_ind; + int32_t tmp_estimates[N_rb_alloc*12] __attribute__((aligned(16))); + + int symbol_offset,i; + + //debug_msg("lte_ul_channel_estimation_RRU: cyclic shift %d\n",cyclicShift); + + 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}; + +#if defined(__x86_64__) || defined(__i386__) + __m128i *rxdataF128,*ul_ref128,*ul_ch128; + __m128i mmtmpU0,mmtmpU1,mmtmpU2,mmtmpU3; +#elif defined(__arm__) + int16x8_t *rxdataF128,*ul_ref128,*ul_ch128; + int32x4_t mmtmp0,mmtmp1,mmtmp_re,mmtmp_im; +#endif + + int32_t temp_in_ifft_0[2048*2] __attribute__((aligned(32))); + + AssertFatal(l==pilot_pos1 || l==pilot_pos2,"%d is not a valid symbol for DMRS, should be %d or %d\n", + l,pilot_pos1,pilot_pos2); + + Msc_RS = N_rb_alloc*12; + /* + + */ + + Msc_idx_ptr = (uint16_t*) bsearch(&Msc_RS, dftsizes, 33, sizeof(uint16_t), compareints); + + if (Msc_idx_ptr) + Msc_RS_idx = Msc_idx_ptr - dftsizes; + else { + LOG_E(PHY,"lte_ul_channel_estimation_RRU: index for Msc_RS=%d not found\n",Msc_RS); + return(-1); + } + LOG_D(PHY,"subframe %d, l %d, Msc_RS = %d, Msc_RS_idx = %d, u %d, v %d, cyclic_shift %d\n",subframe_rx,l,Msc_RS, Msc_RS_idx,u,v,cyclic_shift); +#ifdef DEBUG_CH + if (l==pilot_pos1) + write_output("drs_seq0.m","drsseq0",ul_ref_sigs_rx[u][v][Msc_RS_idx],Msc_RS,1,1); + else + write_output("drs_seq1.m","drsseq1",ul_ref_sigs_rx[u][v][Msc_RS_idx],Msc_RS,1,1); + +#endif + + symbol_offset = frame_parms->N_RB_UL*12*l; + + for (aa=0; aa<nb_antennas_rx; aa++) { + +#if defined(__x86_64__) || defined(__i386__) + rxdataF128 = (__m128i *)&rxdataF_ext[aa][symbol_offset]; + ul_ch128 = (__m128i *)&ul_ch_estimates[aa][symbol_offset]; + ul_ref128 = (__m128i *)ul_ref_sigs_rx[u][v][Msc_RS_idx]; +#elif defined(__arm__) + rxdataF128 = (int16x8_t *)&rxdataF_ext[aa][symbol_offset]; + ul_ch128 = (int16x8_t *)&ul_ch_estimates[aa][symbol_offset]; + ul_ref128 = (int16x8_t *)ul_ref_sigs_rx[u][v][Msc_RS_idx]; +#endif + + for (i=0; i<Msc_RS/12; i++) { +#if defined(__x86_64__) || defined(__i386__) + // multiply by conjugated channel + mmtmpU0 = _mm_madd_epi16(ul_ref128[0],rxdataF128[0]); + // mmtmpU0 contains real part of 4 consecutive outputs (32-bit) + mmtmpU1 = _mm_shufflelo_epi16(ul_ref128[0],_MM_SHUFFLE(2,3,0,1)); + mmtmpU1 = _mm_shufflehi_epi16(mmtmpU1,_MM_SHUFFLE(2,3,0,1)); + mmtmpU1 = _mm_sign_epi16(mmtmpU1,*(__m128i*)&conjugate[0]); + mmtmpU1 = _mm_madd_epi16(mmtmpU1,rxdataF128[0]); + // mmtmpU1 contains imag part of 4 consecutive outputs (32-bit) + mmtmpU0 = _mm_srai_epi32(mmtmpU0,15); + mmtmpU1 = _mm_srai_epi32(mmtmpU1,15); + mmtmpU2 = _mm_unpacklo_epi32(mmtmpU0,mmtmpU1); + mmtmpU3 = _mm_unpackhi_epi32(mmtmpU0,mmtmpU1); + + ul_ch128[0] = _mm_packs_epi32(mmtmpU2,mmtmpU3); + // printf("rb %d ch: %d %d\n",i,((int16_t*)ul_ch128)[0],((int16_t*)ul_ch128)[1]); + // multiply by conjugated channel + mmtmpU0 = _mm_madd_epi16(ul_ref128[1],rxdataF128[1]); + // mmtmpU0 contains real part of 4 consecutive outputs (32-bit) + mmtmpU1 = _mm_shufflelo_epi16(ul_ref128[1],_MM_SHUFFLE(2,3,0,1)); + mmtmpU1 = _mm_shufflehi_epi16(mmtmpU1,_MM_SHUFFLE(2,3,0,1)); + mmtmpU1 = _mm_sign_epi16(mmtmpU1,*(__m128i*)conjugate); + mmtmpU1 = _mm_madd_epi16(mmtmpU1,rxdataF128[1]); + // mmtmpU1 contains imag part of 4 consecutive outputs (32-bit) + mmtmpU0 = _mm_srai_epi32(mmtmpU0,15); + mmtmpU1 = _mm_srai_epi32(mmtmpU1,15); + mmtmpU2 = _mm_unpacklo_epi32(mmtmpU0,mmtmpU1); + mmtmpU3 = _mm_unpackhi_epi32(mmtmpU0,mmtmpU1); + + ul_ch128[1] = _mm_packs_epi32(mmtmpU2,mmtmpU3); + + mmtmpU0 = _mm_madd_epi16(ul_ref128[2],rxdataF128[2]); + // mmtmpU0 contains real part of 4 consecutive outputs (32-bit) + mmtmpU1 = _mm_shufflelo_epi16(ul_ref128[2],_MM_SHUFFLE(2,3,0,1)); + mmtmpU1 = _mm_shufflehi_epi16(mmtmpU1,_MM_SHUFFLE(2,3,0,1)); + mmtmpU1 = _mm_sign_epi16(mmtmpU1,*(__m128i*)conjugate); + mmtmpU1 = _mm_madd_epi16(mmtmpU1,rxdataF128[2]); + // mmtmpU1 contains imag part of 4 consecutive outputs (32-bit) + mmtmpU0 = _mm_srai_epi32(mmtmpU0,15); + mmtmpU1 = _mm_srai_epi32(mmtmpU1,15); + mmtmpU2 = _mm_unpacklo_epi32(mmtmpU0,mmtmpU1); + mmtmpU3 = _mm_unpackhi_epi32(mmtmpU0,mmtmpU1); + + ul_ch128[2] = _mm_packs_epi32(mmtmpU2,mmtmpU3); +#elif defined(__arm__) + mmtmp0 = vmull_s16(((int16x4_t*)ul_ref128)[0],((int16x4_t*)rxdataF128)[0]); + mmtmp1 = vmull_s16(((int16x4_t*)ul_ref128)[1],((int16x4_t*)rxdataF128)[1]); + mmtmp_re = vcombine_s32(vpadd_s32(vget_low_s32(mmtmp0),vget_high_s32(mmtmp0)), + vpadd_s32(vget_low_s32(mmtmp1),vget_high_s32(mmtmp1))); + mmtmp0 = vmull_s16(vrev32_s16(vmul_s16(((int16x4_t*)ul_ref128)[0],*(int16x4_t*)conjugate)), ((int16x4_t*)rxdataF128)[0]); + mmtmp1 = vmull_s16(vrev32_s16(vmul_s16(((int16x4_t*)ul_ref128)[1],*(int16x4_t*)conjugate)), ((int16x4_t*)rxdataF128)[1]); + mmtmp_im = vcombine_s32(vpadd_s32(vget_low_s32(mmtmp0),vget_high_s32(mmtmp0)), + vpadd_s32(vget_low_s32(mmtmp1),vget_high_s32(mmtmp1))); + + ul_ch128[0] = vcombine_s16(vmovn_s32(mmtmp_re),vmovn_s32(mmtmp_im)); + ul_ch128++; + ul_ref128++; + rxdataF128++; + mmtmp0 = vmull_s16(((int16x4_t*)ul_ref128)[0],((int16x4_t*)rxdataF128)[0]); + mmtmp1 = vmull_s16(((int16x4_t*)ul_ref128)[1],((int16x4_t*)rxdataF128)[1]); + mmtmp_re = vcombine_s32(vpadd_s32(vget_low_s32(mmtmp0),vget_high_s32(mmtmp0)), + vpadd_s32(vget_low_s32(mmtmp1),vget_high_s32(mmtmp1))); + mmtmp0 = vmull_s16(vrev32_s16(vmul_s16(((int16x4_t*)ul_ref128)[0],*(int16x4_t*)conjugate)), ((int16x4_t*)rxdataF128)[0]); + mmtmp1 = vmull_s16(vrev32_s16(vmul_s16(((int16x4_t*)ul_ref128)[1],*(int16x4_t*)conjugate)), ((int16x4_t*)rxdataF128)[1]); + mmtmp_im = vcombine_s32(vpadd_s32(vget_low_s32(mmtmp0),vget_high_s32(mmtmp0)), + vpadd_s32(vget_low_s32(mmtmp1),vget_high_s32(mmtmp1))); + + ul_ch128[0] = vcombine_s16(vmovn_s32(mmtmp_re),vmovn_s32(mmtmp_im)); + ul_ch128++; + ul_ref128++; + rxdataF128++; + + mmtmp0 = vmull_s16(((int16x4_t*)ul_ref128)[0],((int16x4_t*)rxdataF128)[0]); + mmtmp1 = vmull_s16(((int16x4_t*)ul_ref128)[1],((int16x4_t*)rxdataF128)[1]); + mmtmp_re = vcombine_s32(vpadd_s32(vget_low_s32(mmtmp0),vget_high_s32(mmtmp0)), + vpadd_s32(vget_low_s32(mmtmp1),vget_high_s32(mmtmp1))); + mmtmp0 = vmull_s16(vrev32_s16(vmul_s16(((int16x4_t*)ul_ref128)[0],*(int16x4_t*)conjugate)), ((int16x4_t*)rxdataF128)[0]); + mmtmp1 = vmull_s16(vrev32_s16(vmul_s16(((int16x4_t*)ul_ref128)[1],*(int16x4_t*)conjugate)), ((int16x4_t*)rxdataF128)[1]); + mmtmp_im = vcombine_s32(vpadd_s32(vget_low_s32(mmtmp0),vget_high_s32(mmtmp0)), + vpadd_s32(vget_low_s32(mmtmp1),vget_high_s32(mmtmp1))); + + ul_ch128[0] = vcombine_s16(vmovn_s32(mmtmp_re),vmovn_s32(mmtmp_im)); + ul_ch128++; + ul_ref128++; + rxdataF128++; + + +#endif + ul_ch128+=3; + ul_ref128+=3; + rxdataF128+=3; + } + + alpha_ind = 0; + + if((cyclic_shift != 0)) { + // Compensating for the phase shift introduced at the transmitte +#ifdef DEBUG_CH + write_output("drs_est_pre.m","drsest_pre",ul_ch_estimates[0],300*12,1,1); +#endif + + for(i=symbol_offset; i<symbol_offset+Msc_RS; i++) { + ul_ch_estimates_re = ((int16_t*) ul_ch_estimates[aa])[i<<1]; + ul_ch_estimates_im = ((int16_t*) ul_ch_estimates[aa])[(i<<1)+1]; + // ((int16_t*) ul_ch_estimates[aa])[i<<1] = (i%2 == 1? 1:-1) * ul_ch_estimates_re; + ((int16_t*) ul_ch_estimates[aa])[i<<1] = + (int16_t) (((int32_t) (alpha_re[alpha_ind]) * (int32_t) (ul_ch_estimates_re) + + (int32_t) (alpha_im[alpha_ind]) * (int32_t) (ul_ch_estimates_im))>>15); + + //((int16_t*) ul_ch_estimates[aa])[(i<<1)+1] = (i%2 == 1? 1:-1) * ul_ch_estimates_im; + ((int16_t*) ul_ch_estimates[aa])[(i<<1)+1] = + (int16_t) (((int32_t) (alpha_re[alpha_ind]) * (int32_t) (ul_ch_estimates_im) - + (int32_t) (alpha_im[alpha_ind]) * (int32_t) (ul_ch_estimates_re))>>15); + + alpha_ind+=cyclic_shift; + + if (alpha_ind>11) + alpha_ind-=12; + } + +#ifdef DEBUG_CH + write_output("drs_est_post.m","drsest_post",ul_ch_estimates[0],300*12,1,1); +#endif + } + + if (ul_ch_estimates_time && ul_ch_estimates_time[aa]) { + // Convert to time domain for visualization + memset(temp_in_ifft_0,0,frame_parms->ofdm_symbol_size*sizeof(int32_t)); + for(i=0; i<Msc_RS; i++) + ((int32_t*)temp_in_ifft_0)[i] = ul_ch_estimates[aa][symbol_offset+i]; + + switch(frame_parms->N_RB_DL) { + case 6: + idft128((int16_t*) temp_in_ifft_0, + (int16_t*) ul_ch_estimates_time[aa], + 1); + break; + case 25: + idft512((int16_t*) temp_in_ifft_0, + (int16_t*) ul_ch_estimates_time[aa], + 1); + break; + case 50: + idft1024((int16_t*) temp_in_ifft_0, + (int16_t*) ul_ch_estimates_time[aa], + 1); + break; + case 100: + idft2048((int16_t*) temp_in_ifft_0, + (int16_t*) ul_ch_estimates_time[aa], + 1); + break; + } + +#if T_TRACER + if (aa == 0) + T(T_ENB_PHY_UL_CHANNEL_ESTIMATE, T_INT(0), T_INT(rnti), + T_INT(frame_rx), T_INT(subframe_rx), + T_INT(0), T_BUFFER(ul_ch_estimates_time[0], 512 * 4)); +#endif + } +#ifdef DEBUG_CH + + if (aa==1) { + if (l == pilot_pos1) { + write_output("rxdataF_ext.m","rxF_ext",&rxdataF_ext[aa][symbol_offset],512*2,2,1); + write_output("tmpin_ifft.m","drs_in",temp_in_ifft_0,512,1,1); + if (ul_ch_estimates_time[aa]) write_output("drs_est0.m","drs0",ul_ch_estimates_time[aa],512,1,1); + } else + if (ul_ch_estimates_time[aa]) write_output("drs_est1.m","drs1",ul_ch_estimates_time[aa],512,1,1); + } + +#endif + + + + + if (l==pilot_pos2 && interpolate==1) {//we are in the second slot of the sub-frame, so do the interpolation + + ul_ch1 = &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*pilot_pos1]; + ul_ch2 = &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*pilot_pos2]; + + + // Estimation of phase difference between the 2 channel estimates + delta_phase = lte_ul_freq_offset_estimation(frame_parms, + ul_ch_estimates[aa], + N_rb_alloc); + // negative phase index indicates negative Im of ru + // msg("delta_phase: %d\n",delta_phase); + +#ifdef DEBUG_CH + LOG_D(PHY,"lte_ul_channel_estimation_RRU: ul_ch1 = %p, ul_ch2 = %p, pilot_pos1=%d, pilot_pos2=%d\n",ul_ch1, ul_ch2, pilot_pos1,pilot_pos2); +#endif + + for (k=0; k<frame_parms->symbols_per_tti; k++) { + +#ifdef DEBUG_CH + // LOG_D(PHY,"lte_ul_channel_estimation: k=%d, alpha = %d, beta = %d\n",k,alpha,beta); +#endif + //symbol_offset_subframe = frame_parms->N_RB_UL*12*k; + + // interpolate between estimates + if ((k != pilot_pos1) && (k != pilot_pos2)) { + + // the phase is linearly interpolated + current_phase1 = (delta_phase/7)*(k-pilot_pos1); + current_phase2 = (delta_phase/7)*(k-pilot_pos2); + // msg("sym: %d, current_phase1: %d, current_phase2: %d\n",k,current_phase1,current_phase2); + // set the right quadrant + (current_phase1 > 0) ? (ru1 = ru_90) : (ru1 = ru_90c); + (current_phase2 > 0) ? (ru2 = ru_90) : (ru2 = ru_90c); + // take absolute value and clip + current_phase1 = cmin(abs(current_phase1),127); + current_phase2 = cmin(abs(current_phase2),127); + + // msg("sym: %d, current_phase1: %d, ru: %d + j%d, current_phase2: %d, ru: %d + j%d\n",k,current_phase1,ru1[2*current_phase1],ru1[2*current_phase1+1],current_phase2,ru2[2*current_phase2],ru2[2*current_phase2+1]); + + // rotate channel estimates by estimated phase + rotate_cpx_vector((int16_t*) ul_ch1, + &ru1[2*current_phase1], + (int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k], + Msc_RS, + 15); + + rotate_cpx_vector((int16_t*) ul_ch2, + &ru2[2*current_phase2], + (int16_t*) &tmp_estimates[0], + Msc_RS, + 15); + + // Combine the two rotated estimates + multadd_complex_vector_real_scalar((int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],SCALE,(int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],1,Msc_RS); + multadd_complex_vector_real_scalar((int16_t*) &tmp_estimates[0],SCALE,(int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],0,Msc_RS); + + } + } //for(k=... + + // because of the scaling of alpha and beta we also need to scale the final channel estimate at the pilot positions + + // multadd_complex_vector_real_scalar((int16_t*) ul_ch1,SCALE,(int16_t*) ul_ch1,1,Msc_RS); + // multadd_complex_vector_real_scalar((int16_t*) ul_ch2,SCALE,(int16_t*) ul_ch2,1,Msc_RS); + + } //if (Ns&1 && interpolate==1) + else if (interpolate == 0 && l == pilot_pos1) + for (k=0;k<frame_parms->symbols_per_tti>>1;k++) { + if (k==pilot_pos1) k++; + memcpy((void*)&ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k], + (void*)&ul_ch_estimates[aa][frame_parms->N_RB_UL*12*pilot_pos1], + frame_parms->N_RB_UL*12*sizeof(int)); + } + else if (interpolate == 0 && l == pilot_pos2) { + for (k=0;k<frame_parms->symbols_per_tti>>1;k++) { + if (k==pilot_pos2) k++; + memcpy((void*)&ul_ch_estimates[aa][frame_parms->N_RB_UL*12*(k+(frame_parms->symbols_per_tti>>1))], + (void*)&ul_ch_estimates[aa][frame_parms->N_RB_UL*12*pilot_pos2], + frame_parms->N_RB_UL*12*sizeof(int)); + } + delta_phase = lte_ul_freq_offset_estimation(frame_parms, + ul_ch_estimates[aa], + N_rb_alloc); + LOG_D(PHY,"delta_phase = %d\n",delta_phase); + } + } //for(aa=... + return(0); +} + extern uint16_t transmission_offset_tdd[16]; //#define DEBUG_SRS diff --git a/openair1/PHY/MODULATION/ul_7_5_kHz.c b/openair1/PHY/MODULATION/ul_7_5_kHz.c index d27a305a5d..c3f13578bb 100644 --- a/openair1/PHY/MODULATION/ul_7_5_kHz.c +++ b/openair1/PHY/MODULATION/ul_7_5_kHz.c @@ -147,6 +147,17 @@ void remove_7_5_kHz(RU_t *ru,uint8_t slot) #endif } - } + // undo 7.5 kHz offset for symbol 3 in case RU is slave (for OTA synchronization) + if (ru->is_slave == 1 && slot == 2){ + memcpy((void*)&rxdata_7_5kHz[aa][(3*frame_parms->ofdm_symbol_size)+ + (2*frame_parms->nb_prefix_samples)+ + frame_parms->nb_prefix_samples0], + (void*)&rxdata[aa][slot_offset+ru->N_TA_offset+ + (3*frame_parms->ofdm_symbol_size)+ + (2*frame_parms->nb_prefix_samples)+ + frame_parms->nb_prefix_samples0], + (frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples)*sizeof(int32_t)); +} +} } diff --git a/openair1/PHY/defs_eNB.h b/openair1/PHY/defs_eNB.h index 5e239123fb..15845add91 100644 --- a/openair1/PHY/defs_eNB.h +++ b/openair1/PHY/defs_eNB.h @@ -301,7 +301,8 @@ typedef enum { RU_READY = 2, RU_RUN = 3, RU_ERROR = 4, - RU_SYNC = 5 + RU_SYNC = 5, + RU_CHECK_SYNC = 6 } rru_state_t; /// Some commamds to RRU. Not sure we should do it like this ! @@ -345,6 +346,8 @@ typedef struct RU_t_s{ int has_ctrl_prt; /// counter to delay start of processing of RU until HW settles int wait_cnt; + /// counter to delay start of slave RUs until stable synchronization + int wait_check; /// Total gain of receive chain uint32_t rx_total_gain_dB; /// number of bands that this device can support @@ -441,6 +444,7 @@ typedef struct RU_t_s{ time_stats_t transport; /// RX and TX buffers for precoder output RU_COMMON common; + RU_CALIBRATION calibration; /// beamforming weight vectors per eNB int32_t **beam_weights[NUMBER_OF_eNB_MAX+1][15]; @@ -480,7 +484,8 @@ typedef enum { RRU_stop=5, RRU_sync_ok=6, RRU_frame_resynch=7, - RRU_MSG_max_num=8 + RRU_MSG_max_num=8, + RRU_check_sync = 9 } rru_config_msg_type_t; typedef struct RRU_CONFIG_msg_s { diff --git a/openair1/PHY/impl_defs_lte.h b/openair1/PHY/impl_defs_lte.h index d649dce100..30980d7ceb 100644 --- a/openair1/PHY/impl_defs_lte.h +++ b/openair1/PHY/impl_defs_lte.h @@ -58,7 +58,7 @@ typedef struct { /// - first index: rx antenna [0..nb_antennas_rx[ /// - second index: ? [0..2*ofdm_symbol_size*frame_parms->symbols_per_tti[ int32_t **rxdataF; - /// \brief Holds output of the sync correlator. + /// \brief Holds output of the sync correlator. /// - first index: sample [0..samples_per_tti*10[ uint32_t *sync_corr; /// \brief Holds the tdd reciprocity calibration coefficients @@ -68,4 +68,19 @@ typedef struct { int32_t **tdd_calib_coeffs; } RU_COMMON; +typedef struct { + /// \brief Received frequency-domain signal after extraction. + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..168*N_RB_DL[ + int32_t **rxdataF_ext; + /// \brief Hold the channel estimates in time domain based on DRS. + /// - first index: rx antenna id [0..nb_antennas_rx[ + /// - second index: ? [0..4*ofdm_symbol_size[ + int32_t **drs_ch_estimates_time; + /// \brief Hold the channel estimates in frequency domain based on DRS. + /// - first index: rx antenna id [0..nb_antennas_rx[ + /// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ + int32_t **drs_ch_estimates; +} RU_CALIBRATION; + #endif diff --git a/openair1/SCHED/ru_procedures.c b/openair1/SCHED/ru_procedures.c index dcd238332f..c99cbcdaea 100644 --- a/openair1/SCHED/ru_procedures.c +++ b/openair1/SCHED/ru_procedures.c @@ -535,7 +535,6 @@ void fep0(RU_t *ru,int slot) { // printf("fep0: slot %d\n",slot); //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX+slot, 1); - remove_7_5_kHz(ru,(slot&1)+(proc->subframe_rx<<1)); for (l=0; l<fp->symbols_per_tti/2; l++) { slot_fep_ul(ru, @@ -647,14 +646,20 @@ extern void kill_feptx_thread(RU_t *ru) void ru_fep_full_2thread(RU_t *ru) { RU_proc_t *proc = &ru->proc; + //PHY_VARS_eNB *eNB = RC.eNB[0][0]; + LTE_DL_FRAME_PARMS *fp = &ru->frame_parms; + RU_CALIBRATION *calibration = &ru->calibration; + + int cnt; + int check_sync_pos; struct timespec wait; - - LTE_DL_FRAME_PARMS *fp=&ru->frame_parms; - - if ((fp->frame_type == TDD) && - (subframe_select(fp,proc->subframe_rx) != SF_UL)) return; - + if (proc->subframe_rx==1){ + //LOG_I(PHY,"subframe type %d, RU %d\n",subframe_select(fp,proc->subframe_rx),ru->idx); + } + else if ((fp->frame_type == TDD) && (subframe_select(fp,proc->subframe_rx) != SF_UL)) { + return; + } //if (ru->idx == 0) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX, 1 ); wait.tv_sec=0; @@ -696,9 +701,73 @@ void ru_fep_full_2thread(RU_t *ru) { stop_meas(&ru->ofdm_demod_wait_stats); if(opp_enabled == 1 && ru->ofdm_demod_wakeup_stats.p_time>30*3000){ print_meas_now(&ru->ofdm_demod_wakeup_stats,"fep wakeup",stderr); - printf("delay in fep wait on codition in frame_rx: %d subframe_rx: %d \n",proc->frame_rx,proc->subframe_rx); + printf("delay in fep wait on condition in frame_rx: %d subframe_rx: %d \n",proc->frame_rx,proc->subframe_rx); } + if (proc->subframe_rx==1 && ru->is_slave==1/* && ru->state == RU_CHECK_SYNC*/) { + + LOG_I(PHY,"Running check synchronization procedure for frame %d\n", proc->frame_rx); + ulsch_extract_rbs_single(ru->common.rxdataF, + calibration->rxdataF_ext, + 0, + fp->N_RB_DL, + 3%(fp->symbols_per_tti/2),// l = symbol within slot + 3/(fp->symbols_per_tti/2),// Ns = slot number + fp); + + + /*lte_ul_channel_estimation((PHY_VARS_eNB *)NULL, + proc, + ru->idx, + 3%(fp->symbols_per_tti/2), + 3/(fp->symbols_per_tti/2)); + */ + lte_ul_channel_estimation_RRU(fp, + calibration->drs_ch_estimates, + calibration->drs_ch_estimates_time, + calibration->rxdataF_ext, + fp->N_RB_DL, //N_rb_alloc, + proc->frame_rx, + proc->subframe_rx, + 0,//u = 0..29 + 0,//v = 0,1 + /*eNB->ulsch[ru->idx]->cyclicShift,cyclic_shift,0..7*/0, + 3,//l, + 0,//interpolate, + 0 /*eNB->ulsch[ru->idx]->rnti rnti or ru->ulsch[eNB_id]->rnti*/); + + + + check_sync_pos = lte_est_timing_advance_pusch((PHY_VARS_eNB *)NULL, + ru->idx); + //LOG_I(PHY,"Estimated check_sync_pos %d\n",check_sync_pos); + if (ru->state == RU_CHECK_SYNC) { + if ((check_sync_pos >= 0 && check_sync_pos<8) || (check_sync_pos < 0 && check_sync_pos>-8)) { + LOG_I(PHY,"check_sync_pos %d, frame %d, cnt %d\n",check_sync_pos,proc->frame_rx,ru->wait_check); + ru->wait_check++; + } + + if (ru->wait_check==10) { + ru->state = RU_RUN; + /*LOG_M("dmrs_time.m","dmrstime",calibration->drs_ch_estimates_time[0], (fp->ofdm_symbol_size),1,1); + LOG_M("rxdataF_ext.m","rxdataFext",&calibration->rxdataF_ext[0][36*fp->N_RB_DL], 12*(fp->N_RB_DL),1,1); + LOG_M("drs_seq0.m","drsseq0",ul_ref_sigs_rx[0][0][23],600,1,1); + LOG_M("rxdata.m","rxdata",&ru->common.rxdata[0][0], fp->samples_per_tti*2,1,1); + exit(-1);*/ + } + } + else if (ru->state == RU_RUN) { + // check for synchronization error + if (check_sync_pos >= 8 || check_sync_pos<=-8) { + exit(-1); + } + } + + else { + AssertFatal(1==0,"Should not get here\n"); + } + } + stop_meas(&ru->ofdm_demod_stats); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX+ru->idx, 0 ); } diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c b/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c index 18e9567402..2336e079eb 100644 --- a/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c +++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c @@ -245,7 +245,7 @@ int trx_eth_write_udp_IF4p5(openair0_device *device, openair0_timestamp timestam } eth->tx_nsamps = nblocks; - printf("Sending %d bytes to %s:%d\n",packet_size,str,ntohs(eth->local_addrd.sin_port)); + //printf("Sending %d bytes to %s:%d\n",packet_size,str,ntohs(eth->local_addrd.sin_port)); bytes_sent = sendto(eth->sockfdd, buff[0], diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index fafcc21b7b..9e55f4f9f5 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -601,7 +601,7 @@ void rx_rf(RU_t *ru,int *frame,int *subframe) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 ); ru->south_in_cnt++; - LOG_I(PHY,"south_in_cnt %d\n",ru->south_in_cnt); + LOG_D(PHY,"south_in_cnt %d\n",ru->south_in_cnt); if (ru->cmd==RU_FRAME_RESYNCH) { LOG_I(PHY,"Applying frame resynch %d => %d\n",*frame,ru->cmdval); @@ -1118,14 +1118,32 @@ void do_ru_synch(RU_t *ru) { ru->rfdevice.trx_set_freq_func(&ru->rfdevice,ru->rfdevice.openair0_cfg,0); */ - ru->state = RU_RUN; - // Send RRU_sync_ok - rru_config_msg.type = RRU_sync_ok; + + // Verification of synchronization procedure + ru->state = RU_CHECK_SYNC; + /* // Send RRU_check_sync + rru_config_msg.type = RRU_check_sync; rru_config_msg.len = sizeof(RRU_CONFIG_msg_t); // TODO: set to correct msg len - - LOG_I(PHY,"Sending RRU_sync_ok to RAU\n"); + LOG_I(PHY,"Sending RRU_check_sync to RAU\n"); AssertFatal((ru->ifdevice.trx_ctlsend_func(&ru->ifdevice,&rru_config_msg,rru_config_msg.len)!=-1),"Failed to send msg to RAU %d\n",ru->idx); + + while (check_sync_flag){ // continuously read frames until check synch procedure is over + + } + + //if (synch_peak>...) { + ru->state = RU_RUN; + // Send RRU_sync_ok + rru_config_msg.type = RRU_sync_ok; + rru_config_msg.len = sizeof(RRU_CONFIG_msg_t); // TODO: set to correct msg len + LOG_I(PHY,"Sending RRU_sync_ok to RAU\n"); + AssertFatal((ru->ifdevice.trx_ctlsend_func(&ru->ifdevice,&rru_config_msg,rru_config_msg.len)!=-1),"Failed to send msg to RAU %d\n",ru->idx); + //} + //else { + //do_ru_synch(ru); + //} +*/ LOG_I(PHY,"Exiting synch routine\n"); } @@ -1653,8 +1671,14 @@ static void* ru_thread( void* param ) { while (!oai_exit) { - if (ru->if_south != LOCAL_RF && ru->is_slave==1) ru->wait_cnt = 100; - else ru->wait_cnt = 0; + if (ru->if_south != LOCAL_RF && ru->is_slave==1) { + ru->wait_cnt = 100; + } + else { + ru->wait_cnt = 0; + ru->wait_check = 0; + } + // wait to be woken up if (ru->function!=eNodeB_3GPP && ru->has_ctrl_prt == 1) { @@ -1663,7 +1687,7 @@ static void* ru_thread( void* param ) { else wait_sync("ru_thread"); if (ru->is_slave == 0) AssertFatal(ru->state == RU_RUN,"ru-%d state = %s != RU_RUN\n",ru->idx,ru_states[ru->state]); - else if (ru->is_slave == 1) AssertFatal(ru->state == RU_SYNC || ru->state == RU_RUN,"ru %d state = %s != RU_SYNC or RU_RUN\n",ru->idx,ru_states[ru->state]); + else if (ru->is_slave == 1) AssertFatal(ru->state == RU_SYNC || ru->state == RU_RUN || ru->state == RU_CHECK_SYNC,"ru %d state = %s != RU_SYNC or RU_RUN or RU_CHECK_SYNC\n",ru->idx,ru_states[ru->state]); // Start RF device if any if (ru->start_rf) { if (ru->start_rf(ru) != 0) @@ -1691,7 +1715,7 @@ static void* ru_thread( void* param ) { LOG_D(PHY,"Starting steady-state operation\n"); // This is a forever while loop, it loops over subframes which are scheduled by incoming samples from HW devices - while (ru->state == RU_RUN) { + while (ru->state == RU_RUN || ru->state == RU_CHECK_SYNC) { // these are local subframe/frame counters to check that we are in synch with the fronthaul timing. // They are set on the first rx/tx in the underly FH routines. @@ -1841,7 +1865,7 @@ static void* ru_thread( void* param ) { // do outgoing fronthaul (south) if needed if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru); - if (ru->fh_north_out) ru->fh_north_out(ru); + if ((ru->fh_north_out) && (ru->state!=RU_CHECK_SYNC)) ru->fh_north_out(ru); } proc->emulate_rf_busy = 0; } @@ -1907,15 +1931,16 @@ void *ru_thread_synch(void *arg) { &avg); LOG_I(PHY,"RU synch cnt %d: %d, val %llu (%d dB,%d dB)\n",cnt,ru->rx_offset,(unsigned long long)peak_val,dB_fixed64(peak_val),dB_fixed64(avg)); cnt++; - if (/*ru->rx_offset >= 0*/dB_fixed64(peak_val)>=85 && cnt>10) { + if (/*ru->rx_offset >= 0*/dB_fixed(peak_val)>=85 && cnt>10) { LOG_I(PHY,"Estimated peak_val %d dB, avg %d => timing offset %llu\n",dB_fixed(peak_val),dB_fixed(avg),(unsigned long long int)ru->rx_offset); ru->in_synch = 1; - +/* LOG_M("ru_sync_rx.m","rurx",&ru->common.rxdata[0][0],LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_tti,1,1); LOG_M("ru_sync_corr.m","sync_corr",ru->dmrs_corr,LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_tti,1,6); LOG_M("ru_dmrs.m","rudmrs",&ru->dmrssync[0],fp->ofdm_symbol_size,1,1); - //exit(-1); + */ +//exit(-1); } // sync_pos > 0 else //AssertFatal(cnt<1000,"Cannot find synch reference\n"); { -- 2.26.2