Commit 0ed5a4b5 authored by lfarizav's avatar lfarizav

frequency analysis

parent 1fb76157
......@@ -1108,6 +1108,15 @@ int phy_init_lte_ue(PHY_VARS_UE *ue,
// many memory allocation sizes are hard coded
AssertFatal( fp->nb_antennas_rx <= 2, "hard coded allocation for ue_common_vars->dl_ch_estimates[eNB_id]" );
AssertFatal( ue->n_connected_eNB <= NUMBER_OF_CONNECTED_eNB_MAX, "n_connected_eNB is too large" );
// do_ofdm_mod for frequency analysis
int do_ofdm_mod = ue->do_ofdm_mod=1;
if (do_ofdm_mod==0)
LOG_D(PHY,"Frequency domain deactivated. do_ofdm_mod flag is initialized in %d.\n",ue->do_ofdm_mod);
else
LOG_D(PHY,"Frequency domain activated. do_ofdm_mod flag is initialized in %d.\n ",ue->do_ofdm_mod);
// init phy_vars_ue
for (i=0; i<4; i++) {
......@@ -1138,7 +1147,7 @@ int phy_init_lte_ue(PHY_VARS_UE *ue,
for (i=0; i<fp->nb_antennas_tx; i++) {
common_vars->txdata[i] = (int32_t*)malloc16_clear( fp->samples_per_tti*10*sizeof(int32_t) );
common_vars->txdataF[i] = (int32_t *)malloc16_clear( fp->ofdm_symbol_size*fp->symbols_per_tti*10*sizeof(int32_t) );
common_vars->txdataF[i] = (int32_t *)malloc16_clear( (fp->ofdm_symbol_size*fp->symbols_per_tti*10)*sizeof(int32_t) );
}
// init RX buffers
......@@ -1151,7 +1160,7 @@ int phy_init_lte_ue(PHY_VARS_UE *ue,
for (i=0; i<fp->nb_antennas_rx; i++) {
common_vars->rxdata[i] = (int32_t*) malloc16_clear( (fp->samples_per_tti*10+2048)*sizeof(int32_t) );
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
common_vars->common_vars_rx_data_per_thread[th_id].rxdataF[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*(fp->ofdm_symbol_size*14) );
common_vars->common_vars_rx_data_per_thread[th_id].rxdataF[i] = (int32_t*)malloc16_clear((fp->ofdm_symbol_size*14)*sizeof(int32_t));
}
}
}
......
......@@ -116,6 +116,14 @@ int lte_dl_channel_estimation(PHY_VARS_UE *phy_vars_ue,
uint8_t l,
uint8_t symbol);
int lte_dl_channel_estimation_freq(PHY_VARS_UE *phy_vars_ue,
module_id_t eNB_id,
uint8_t eNB_offset,
uint8_t Ns,
uint8_t p,
uint8_t l,
uint8_t symbol);
int lte_dl_bf_channel_estimation(PHY_VARS_UE *phy_vars_ue,
module_id_t eNB_id,
uint8_t eNB_offset,
......@@ -130,6 +138,13 @@ int lte_dl_msbfn_channel_estimation(PHY_VARS_UE *phy_vars_ue,
unsigned char l,
unsigned char symbol);
int lte_dl_msbfn_channel_estimation_freq(PHY_VARS_UE *phy_vars_ue,
module_id_t eNB_id,
uint8_t eNB_offset,
int subframe,
unsigned char l,
unsigned char symbol);
int lte_dl_mbsfn_channel_estimation(PHY_VARS_UE *phy_vars_ue,
module_id_t eNB_id,
uint8_t eNB_offset,
......@@ -197,6 +212,10 @@ void ue_rrc_measurements(PHY_VARS_UE *phy_vars_ue,
uint8_t slot,
uint8_t abstraction_flag);
void ue_rrc_measurements_freq(PHY_VARS_UE *phy_vars_ue,
uint8_t slot,
uint8_t abstraction_flag);
void lte_ue_measurements_emul(PHY_VARS_UE *phy_vars_ue,uint8_t last_slot,uint8_t eNB_id);
/*! \brief Function to return the path-loss based on the UE cell-specific reference signal strength and transmission power of eNB
......
......@@ -819,4 +819,795 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue,
return(0);
}
int lte_dl_channel_estimation_freq(PHY_VARS_UE *ue,
uint8_t eNB_id,
uint8_t eNB_offset,
unsigned char Ns,
unsigned char p,
unsigned char l,
unsigned char symbol)
{
int pilot[2][200] __attribute__((aligned(16)));
unsigned char nu,aarx;
unsigned short k;
unsigned int rb,pilot_cnt;
int16_t ch[2],*pil,*rxF,*dl_ch,*dl_ch_prev,*f,*f2,*fl,*f2l2,*fr,*f2r2,*f2_dc,*f_dc;
int ch_offset,symbol_offset;
// unsigned int n;
// int i;
static int interpolateS11S12 = 1;
uint16_t Nid_cell = (eNB_offset == 0) ? ue->frame_parms.Nid_cell : ue->measurements.adj_cell_id[eNB_offset-1];
uint8_t nushift,pilot0,pilot1,pilot2,pilot3;
uint8_t previous_thread_id = ue->current_thread_id[Ns>>1]==0 ? (RX_NB_TH-1):(ue->current_thread_id[Ns>>1]-1);
int **dl_ch_estimates =ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates[eNB_offset];
int **dl_ch_estimates_previous=ue->common_vars.common_vars_rx_data_per_thread[previous_thread_id].dl_ch_estimates[eNB_offset];
int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF;
int subframe = Ns>>1;
pilot0 = 0;
if (ue->frame_parms.Ncp == 0) { // normal prefix
pilot1 = 4;
pilot2 = 7;
pilot3 = 11;
} else { // extended prefix
pilot1 = 3;
pilot2 = 6;
pilot3 = 9;
}
// recompute nushift with eNB_offset corresponding to adjacent eNB on which to perform channel estimation
nushift = Nid_cell%6;
if ((p==0) && (l==0) )
nu = 0;
else if ((p==0) && (l>0))
nu = 3;
else if ((p==1) && (l==0))
nu = 3;
else if ((p==1) && (l>0))
nu = 0;
else {
msg("lte_dl_channel_estimation: p %d, l %d -> ERROR\n",p,l);
return(-1);
}
//ch_offset = (l*(ue->frame_parms.ofdm_symbol_size));
if (ue->high_speed_flag == 0) // use second channel estimate position for temporary storage
ch_offset = ue->frame_parms.ofdm_symbol_size ;
else
ch_offset = ue->frame_parms.ofdm_symbol_size*symbol;
symbol_offset = ue->frame_parms.ofdm_symbol_size*symbol;
k = (nu + nushift)%6;
#ifdef DEBUG_CH
printf("Channel Estimation : ThreadId %d, eNB_offset %d cell_id %d ch_offset %d, OFDM size %d, Ncp=%d, l=%d, Ns=%d, k=%d\n",ue->current_thread_id[Ns>>1], eNB_offset,Nid_cell,ch_offset,ue->frame_parms.ofdm_symbol_size,
ue->frame_parms.Ncp,l,Ns,k);
#endif
switch (k) {
case 0 :
f=filt24_0; //for first pilot of RB, first half
f2=filt24_2; //for second pilot of RB, first half
fl=filt24_0; //for first pilot of leftmost RB
f2l2=filt24_2;
// fr=filt24_2r; //for first pilot of rightmost RB
fr=filt24_0r2; //for first pilot of rightmost RB
// f2r2=filt24_0r2;
f2r2=filt24_2r;
f_dc=filt24_0_dcr;
f2_dc=filt24_2_dcl;
break;
case 1 :
f=filt24_1;
f2=filt24_3;
fl=filt24_1l;
f2l2=filt24_3l2;
fr=filt24_1r2;
f2r2=filt24_3r;
f_dc=filt24_1_dcr; //for first pilot of RB, first half
f2_dc=filt24_3_dcl; //for first pilot of RB, first half
break;
case 2 :
f=filt24_2;
f2=filt24_4;
fl=filt24_2l;
f2l2=filt24_4l2;
fr=filt24_2r2;
f2r2=filt24_4r;
f_dc=filt24_2_dcr; //for first pilot of RB, first half
f2_dc=filt24_4_dcl; //for first pilot of RB, first half
break;
case 3 :
f=filt24_3;
f2=filt24_5;
fl=filt24_3l;
f2l2=filt24_5l2;
fr=filt24_3r2;
f2r2=filt24_5r;
f_dc=filt24_3_dcr; //for first pilot of RB, first half
f2_dc=filt24_5_dcl; //for first pilot of RB, first half
break;
case 4 :
f=filt24_4;
f2=filt24_6;
fl=filt24_4l;
f2l2=filt24_6l2;
fr=filt24_4r2;
f2r2=filt24_6r;
f_dc=filt24_4_dcr; //for first pilot of RB, first half
f2_dc=filt24_6_dcl; //for first pilot of RB, first half
break;
case 5 :
f=filt24_5;
f2=filt24_7;
fl=filt24_5l;
f2l2=filt24_7l2;
fr=filt24_5r2;
f2r2=filt24_7r;
f_dc=filt24_5_dcr; //for first pilot of RB, first half
f2_dc=filt24_7_dcl; //for first pilot of RB, first half
break;
default:
msg("lte_dl_channel_estimation: k=%d -> ERROR\n",k);
return(-1);
break;
}
// generate pilot
lte_dl_cell_spec_rx(ue,
eNB_offset,
&pilot[p][0],
Ns,
(l==0)?0:1,
p);
for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
pil = (int16_t *)&pilot[p][0];
rxF = (int16_t *)&rxdataF[aarx][((symbol_offset+k+ue->frame_parms.first_carrier_offset))+subframe*(ue->frame_parms.ofdm_symbol_size*ue->frame_parms.symbols_per_tti)];
dl_ch = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][ch_offset];
// if (eNb_id==0)
memset(dl_ch,0,4*(ue->frame_parms.ofdm_symbol_size));
if (ue->high_speed_flag==0) // multiply previous channel estimate by ch_est_alpha
multadd_complex_vector_real_scalar(dl_ch-(ue->frame_parms.ofdm_symbol_size<<1),
ue->ch_est_alpha,dl_ch-(ue->frame_parms.ofdm_symbol_size<<1),
1,ue->frame_parms.ofdm_symbol_size);
#ifdef DEBUG_CH
printf("k %d, first_carrier %d\n",k,ue->frame_parms.first_carrier_offset);
#endif
if ((ue->frame_parms.N_RB_DL==6) ||
(ue->frame_parms.N_RB_DL==50) ||
(ue->frame_parms.N_RB_DL==100)) {
//First half of pilots
// Treat first 2 pilots specially (left edge)
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_CH
printf("pilot 0 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
multadd_real_vector_complex_scalar(fl,
ch,
dl_ch,
24);
pil+=2; // Re Im
rxF+=12;
dl_ch+=8;
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_CH
printf("pilot 1 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
multadd_real_vector_complex_scalar(f2l2,
ch,
dl_ch,
24);
pil+=2;
rxF+=12;
dl_ch+=16;
for (pilot_cnt=2; pilot_cnt<((ue->frame_parms.N_RB_DL)-1); pilot_cnt+=2) {
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); //Re
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); //Im
#ifdef DEBUG_CH
printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
multadd_real_vector_complex_scalar(f,
ch,
dl_ch,
24);
pil+=2; // Re Im
rxF+=12;
dl_ch+=8;
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_CH
printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
multadd_real_vector_complex_scalar(f2,
ch,
dl_ch,
24);
pil+=2;
rxF+=12;
dl_ch+=16;
}
// printf("Second half\n");
// Second half of RBs
k = (nu + nushift)%6;
if (k > 6)
k -=6;
rxF = (int16_t *)&rxdataF[aarx][((symbol_offset+1+k))+subframe*(ue->frame_parms.ofdm_symbol_size*ue->frame_parms.symbols_per_tti)];
#ifdef DEBUG_CH
printf("second half k %d\n",k);
#endif
for (pilot_cnt=0; pilot_cnt<((ue->frame_parms.N_RB_DL)-3); pilot_cnt+=2) {
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_CH
printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
multadd_real_vector_complex_scalar(f,
ch,
dl_ch,
24);
pil+=2;
rxF+=12;
dl_ch+=8;
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_CH
printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
multadd_real_vector_complex_scalar(f2,
ch,
dl_ch,
24);
pil+=2;
rxF+=12;
dl_ch+=16;
}
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_CH
printf("pilot %d: rxF -> (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
multadd_real_vector_complex_scalar(fr,
ch,
dl_ch,
24);
pil+=2; // Re Im
rxF+=12;
dl_ch+=8;
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_CH
printf("pilot %d: rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
multadd_real_vector_complex_scalar(f2r2,
ch,
dl_ch,
24);
}
else if (ue->frame_parms.N_RB_DL==25) {
//printf("Channel estimation\n");
// Treat first 2 pilots specially (left edge)
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_CH
printf("pilot 0 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
// ch[0] = 1024;
// ch[1] = -128;
#endif
multadd_real_vector_complex_scalar(fl,
ch,
dl_ch,
24);
pil+=2; // Re Im
rxF+=12;
dl_ch+=8;
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_CH
printf("pilot 1 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
// ch[0] = 1024;
// ch[1] = -128;
#endif
multadd_real_vector_complex_scalar(f2l2,
ch,
dl_ch,
24);
pil+=2;
rxF+=12;
dl_ch+=16;
for (pilot_cnt=2; pilot_cnt<24; pilot_cnt+=2) {
// printf("pilot[%d][%d] (%d,%d)\n",p,rb,pil[0],pil[1]);
// printf("rx[%d][%d] -> (%d,%d)\n",p,ue->frame_parms.first_carrier_offset + ue->frame_parms.nushift + 6*rb+(3*p),rxF[0],rxF[1]);
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_CH
printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
// ch[0] = 1024;
// ch[1] = -128;
#endif
multadd_real_vector_complex_scalar(f,
ch,
dl_ch,
24);
pil+=2; // Re Im
rxF+=12;
dl_ch+=8;
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_CH
printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
// ch[0] = 1024;
// ch[1] = -128;
#endif
multadd_real_vector_complex_scalar(f2,
ch,
dl_ch,
24);
pil+=2;
rxF+=12;
dl_ch+=16;
}
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_CH
printf("pilot 24: rxF -> (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
// ch[0] = 1024;
// ch[1] = -128;
#endif
multadd_real_vector_complex_scalar(f_dc,
ch,
dl_ch,
24);
pil+=2; // Re Im
dl_ch+=8;
// printf("Second half\n");
// Second half of RBs
rxF = (int16_t *)&rxdataF[aarx][((symbol_offset+1+k))+subframe*(ue->frame_parms.ofdm_symbol_size*ue->frame_parms.symbols_per_tti)];
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_CH
printf("pilot 25: rxF -> (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
// ch[0] = 1024;
// ch[1] = -128;
#endif
multadd_real_vector_complex_scalar(f2_dc,
ch,
dl_ch,
24);
pil+=2;
rxF+=12;
dl_ch+=16;
for (pilot_cnt=0; pilot_cnt<22; pilot_cnt+=2) {
// printf("* pilot[%d][%d] (%d,%d)\n",p,rb,pil[0],pil[1]);
// printf("rx[%d][%d] -> (%d,%d)\n",p,ue->frame_parms.first_carrier_offset + ue->frame_parms.nushift + 6*rb+(3*p),rxF[0],rxF[1]);
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_CH
printf("pilot %d rxF -> (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",26+pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
// ch[0] = 1024;
// ch[1] = -128;
#endif
multadd_real_vector_complex_scalar(f,
ch,
dl_ch,
24);
pil+=2;
rxF+=12;
dl_ch+=8;
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_CH
printf("pilot %d : rxF -> (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",27+pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
// ch[0] = 1024;
// ch[1] = -128;
#endif
multadd_real_vector_complex_scalar(f2,
ch,
dl_ch,
24);
pil+=2;
rxF+=12;
dl_ch+=16;
}
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_CH
printf("pilot 49: rxF -> (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
// ch[0] = 1024;
// ch[1] = -128;
#endif
multadd_real_vector_complex_scalar(fr,
ch,
dl_ch,
24);
pil+=2; // Re Im
rxF+=12;
dl_ch+=8;
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_CH
printf("pilot 50: rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
// ch[0] = 1024;
// ch[1] = -128;
#endif
multadd_real_vector_complex_scalar(f2r2,
ch,
dl_ch,
24);
} else if (ue->frame_parms.N_RB_DL==15) {
//printf("First Half\n");
for (rb=0; rb<28; rb+=4) {
//printf("aarx=%d\n",aarx);
//printf("pilot[%d][%d] (%d,%d)\n",p,rb,pil[0],pil[1]);
//printf("rx[%d][%d] -> (%d,%d)\n",p,
// ue->frame_parms.first_carrier_offset + ue->frame_parms.nushift + 6*rb+(3*p),
// rxF[0],
// rxF[1]);
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
//printf("ch -> (%d,%d)\n",ch[0],ch[1]);
multadd_real_vector_complex_scalar(f,
ch,
dl_ch,
24);
pil+=2; // Re Im
rxF+=12;
dl_ch+=8;
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
//printf("ch -> (%d,%d)\n",ch[0],ch[1]);
multadd_real_vector_complex_scalar(f2,
ch,
dl_ch,
24);
pil+=2;
rxF+=12;
dl_ch+=16;
}
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
// printf("ch -> (%d,%d)\n",ch[0],ch[1]);
multadd_real_vector_complex_scalar(f,
ch,
dl_ch,
24);
pil+=2; // Re Im
dl_ch+=8;
//printf("Second half\n");
//Second half of RBs
rxF = (int16_t *)&rxdataF[aarx][((symbol_offset+1+nushift + (3*p)))+subframe*(ue->frame_parms.ofdm_symbol_size*ue->frame_parms.symbols_per_tti)];
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
multadd_real_vector_complex_scalar(f2,
ch,
dl_ch,
24);
pil+=2;
rxF+=12;
dl_ch+=16;
for (rb=0; rb<28; rb+=4) {
//printf("aarx=%d\n",aarx);
//printf("pilot[%d][%d] (%d,%d)\n",p,rb,pil[0],pil[1]);
//printf("rx[%d][%d] -> (%d,%d)\n",p,
// ue->frame_parms.first_carrier_offset + ue->frame_parms.nushift + 6*rb+(3*p),
// rxF[0],
// rxF[1]);
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
multadd_real_vector_complex_scalar(f,
ch,
dl_ch,
24);
pil+=2;
rxF+=12;
dl_ch+=8;
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
multadd_real_vector_complex_scalar(f2,
ch,
dl_ch,
24);
pil+=2;
rxF+=12;
dl_ch+=16;
}
} else {
msg("channel estimation not implemented for ue->frame_parms.N_RB_DL = %d\n",ue->frame_parms.N_RB_DL);
}
if (ue->perfect_ce == 0) {
// Temporal Interpolation
// printf("ch_offset %d\n",ch_offset);
dl_ch = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][ch_offset];
if (ue->high_speed_flag == 0) {
multadd_complex_vector_real_scalar(dl_ch,
32767-ue->ch_est_alpha,
dl_ch-(ue->frame_parms.ofdm_symbol_size<<1),0,ue->frame_parms.ofdm_symbol_size);
} else { // high_speed_flag == 1
if ((symbol == 0)) {
// printf("Interpolating %d->0\n",4-ue->frame_parms.Ncp);
// dl_ch_prev = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][(4-ue->frame_parms.Ncp)*(ue->frame_parms.ofdm_symbol_size)];
if(((Ns>>1)!=0) || ( ((Ns>>1)==0) && interpolateS11S12))
{
//LOG_I(PHY,"Interpolate s11-->s0 to get s12 and s13 Ns %d \n", Ns);
dl_ch_prev = (int16_t *)&dl_ch_estimates_previous[(p<<1)+aarx][pilot3*(ue->frame_parms.ofdm_symbol_size)];
multadd_complex_vector_real_scalar(dl_ch_prev,21845,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch,10923,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch_prev,10923,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch,21845,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),0,ue->frame_parms.ofdm_symbol_size);
}
interpolateS11S12 = 1;
} // this is 1/3,2/3 combination for pilots spaced by 3 symbols
else if (symbol == pilot1) {
dl_ch_prev = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][0];
//LOG_I(PHY,"Interpolate s0-->s4 to get s1 s2 and s3 Ns %d \n", Ns);
if (ue->frame_parms.Ncp==0) {// pilot spacing 4 symbols (1/4,1/2,3/4 combination)
uint8_t previous_subframe;
if(Ns>>1 == 0)
previous_subframe = 9;
else
previous_subframe = ((Ns>>1) - 1 )%9;
if((subframe_select(&ue->frame_parms,previous_subframe) == SF_UL))
{
multadd_complex_vector_real_scalar(dl_ch_prev,328,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch,32440,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch_prev,328,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch,32440,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),0,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch_prev,8192,dl_ch_prev+(3*2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch,32440,dl_ch_prev+(3*2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size);
}
else
{
multadd_complex_vector_real_scalar(dl_ch_prev,24576,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch,8192,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch_prev,16384,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch,16384,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),0,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch_prev,8192,dl_ch_prev+(3*2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch,24576,dl_ch_prev+(3*2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size);
}
} else {
multadd_complex_vector_real_scalar(dl_ch_prev,328,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch,21845,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch_prev,21845,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)<<1),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch,10923,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),0,ue->frame_parms.ofdm_symbol_size);
} // pilot spacing 3 symbols (1/3,2/3 combination)
} else if (symbol == pilot2) {
dl_ch_prev = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][pilot1*(ue->frame_parms.ofdm_symbol_size)];
multadd_complex_vector_real_scalar(dl_ch_prev,21845,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch,10923,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch_prev,10923,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch,21845,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),0,ue->frame_parms.ofdm_symbol_size);
} else { // symbol == pilot3
// printf("Interpolating 0->%d\n",4-ue->frame_parms.Ncp);
dl_ch_prev = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][pilot2*(ue->frame_parms.ofdm_symbol_size)];
if (ue->frame_parms.Ncp==0) {// pilot spacing 4 symbols (1/4,1/2,3/4 combination)
multadd_complex_vector_real_scalar(dl_ch_prev,24576,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch,8192,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch_prev,16384,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch,16384,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),0,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch_prev,8192,dl_ch_prev+(3*2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch,24576,dl_ch_prev+(3*2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size);
} else {
multadd_complex_vector_real_scalar(dl_ch_prev,10923,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch,21845,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch_prev,21845,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)<<1),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch,10923,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),0,ue->frame_parms.ofdm_symbol_size);
} // pilot spacing 3 symbols (1/3,2/3 combination)
if((ue->rx_offset_diff !=0) && ((Ns>>1) == 9))
{
//LOG_I(PHY,"Extrapolate s7-->s11 to get s12 and s13 Ns %d\n", Ns);
interpolateS11S12 = 0;
//LOG_E(PHY,"Interpolate s7--s11 s12 s13 pilot 3 Ns %d l %d symbol %d \n", Ns, l, symbol);
int16_t *dlChEst_ofdm11 = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][pilot3*(ue->frame_parms.ofdm_symbol_size)];
int16_t *dlChEst_ofdm7 = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][pilot2*(ue->frame_parms.ofdm_symbol_size)];
// interpolate ofdm s12: 5/4*ofdms11 + -1/4*ofdms7 5/4 q1.15 40960 -1/4 q1.15 8192
int16_t *dlChEst_ofdm12 = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][12*ue->frame_parms.ofdm_symbol_size];
for(int i=0; i<(2*ue->frame_parms.ofdm_symbol_size); i++)
{
int64_t tmp_mult = 0;
tmp_mult = ((int64_t)dlChEst_ofdm11[i] * 40960 - (int64_t)dlChEst_ofdm7[i] * 8192);
tmp_mult = tmp_mult >> 15;
dlChEst_ofdm12[i] = tmp_mult;
}
// interpolate ofdm s13: 3/2*ofdms11 + -1/2*ofdms7 3/2 q1.15 49152 1/2 q1.15 16384
int16_t *dlChEst_ofdm13 = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][13*ue->frame_parms.ofdm_symbol_size];
for(int i=0; i<(2*ue->frame_parms.ofdm_symbol_size); i++)
{
int64_t tmp_mult = 0;
tmp_mult = ((int64_t)dlChEst_ofdm11[i] * 49152 - (int64_t)dlChEst_ofdm7[i] * 16384);
tmp_mult = tmp_mult >> 15;
dlChEst_ofdm13[i] = tmp_mult;
}
}
}
}
}
}
/*void (*idft)(int16_t *,int16_t *, int);
switch (ue->frame_parms.ofdm_symbol_size) {
case 128:
idft = idft128;
break;
case 256:
idft = idft256;
break;
case 512:
idft = idft512;
break;
case 1024:
idft = idft1024;
break;
case 1536:
idft = idft1536;
break;
case 2048:
idft = idft2048;
break;
default:
idft = idft512;
break;
}
if( ((Ns%2) == 0) && (l == pilot0))
{
// do ifft of channel estimate
for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++)
for (p=0; p<ue->frame_parms.nb_antenna_ports_eNB; p++) {
if (ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates[eNB_offset][(p<<1)+aarx])
{
//LOG_I(PHY,"Channel Impulse Computation Slot %d ThreadId %d Symbol %d \n", Ns, ue->current_thread_id[Ns>>1], l);
idft((int16_t*) &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates[eNB_offset][(p<<1)+aarx][8],
(int16_t*) ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates_time[eNB_offset][(p<<1)+aarx],1);
}
}
}
#if T_TRACER
T(T_UE_PHY_DL_CHANNEL_ESTIMATE, T_INT(eNB_id), T_INT(ue->Mod_id),
T_INT(ue->proc.proc_rxtx[ue->current_thread_id[Ns>>1]].frame_rx%1024), T_INT(ue->proc.proc_rxtx[ue->current_thread_id[Ns>>1]].subframe_rx),
T_INT(0), T_BUFFER(&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates_time[eNB_offset][0][0], 512 * 4));
#endif*/
return(0);
}
......@@ -769,4 +769,749 @@ int lte_dl_mbsfn_channel_estimation(PHY_VARS_UE *ue,
return(0);
}
int lte_dl_mbsfn_channel_estimation_freq(PHY_VARS_UE *ue,
uint8_t eNB_id,
uint8_t eNB_offset,
int subframe,
unsigned char l)
{
int pilot[600] __attribute__((aligned(16)));
unsigned char aarx,aa;
unsigned int rb;
short *pil,*rxF,*ch,*ch0,*ch1,*ch11,*chp,*ch_prev;
int ch_offset,symbol_offset;
// unsigned int n;
// int i;
int **dl_ch_estimates=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[0];
int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF;
ch_offset = (l*(ue->frame_parms.ofdm_symbol_size));
symbol_offset = ch_offset;//phy_vars_ue->lte_frame_parms.ofdm_symbol_size*l;
for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
// generate pilot
if ((l==2)||(l==6)||(l==10)) {
lte_dl_mbsfn_rx(ue,
&pilot[0],
subframe,
l>>2);
} // if symbol==2, return 0 else if symbol = 6, return 1, else if symbol=10 return 2
pil = (short *)&pilot[0];
rxF = (short *)&rxdataF[aarx][((symbol_offset+ue->frame_parms.first_carrier_offset))+subframe*(ue->frame_parms.symbols_per_tti*ue->frame_parms.ofdm_symbol_size)];
ch = (short *)&dl_ch_estimates[aarx][ch_offset];
// if (eNb_id==0)
memset(ch,0,4*(ue->frame_parms.ofdm_symbol_size));
//***********************************************************************
if ((ue->frame_parms.N_RB_DL==6) ||
(ue->frame_parms.N_RB_DL==50) ||
(ue->frame_parms.N_RB_DL==100)) {
// Interpolation and extrapolation;
if (l==6) {
// ________________________First half of RBs____________________
ch+=2;
rxF+=2;
}
for (rb=0; rb<ue->frame_parms.N_RB_DL; rb++) {
// ------------------------1st pilot------------------------
if (rb==(ue->frame_parms.N_RB_DL>>1)) {
rxF = (short *)&rxdataF[aarx][symbol_offset+1+subframe*(ue->frame_parms.symbols_per_tti*ue->frame_parms.ofdm_symbol_size)];
if (l==6)
rxF+=2;
}
ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15);
ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15);
ch[2] = ch[0]>>1;
ch[3] = ch[1]>>1;
/*
printf("rb %d: pil0 (%d,%d) x (%d,%d) = (%d,%d)\n",
rb,pil[0],pil[1],rxF[0],rxF[1],ch[0],ch[1]);*/
if ((rb>0)&&(rb!=(ue->frame_parms.N_RB_DL>>1))) {
ch[-2] += ch[2];
ch[-1] += ch[3];
} else {
ch[-2]= ch[0];
ch[-1]= ch[1];
}
// ------------------------2nd pilot------------------------
ch[4] = (short)(((int)pil[2]*rxF[4] - (int)pil[3]*rxF[5])>>15);
ch[5] = (short)(((int)pil[2]*rxF[5] + (int)pil[3]*rxF[4])>>15);
ch[6] = ch[4]>>1;
ch[7] = ch[5]>>1;
ch[2] += ch[6];
ch[3] += ch[7];
/* printf("rb %d: pil1 (%d,%d) x (%d,%d) = (%d,%d)\n",
rb,pil[2],pil[3],rxF[4],rxF[5],ch[4],ch[5]);*/
// ------------------------3rd pilot------------------------
ch[8] = (short)(((int)pil[4]*rxF[8] - (int)pil[5]*rxF[9])>>15);
ch[9] = (short)(((int)pil[4]*rxF[9] + (int)pil[5]*rxF[8])>>15);
ch[10] = ch[8]>>1;
ch[11] = ch[9]>>1;
ch[6] += ch[10];
ch[7] += ch[11];
/* printf("rb %d: pil2 (%d,%d) x (%d,%d) = (%d,%d)\n",
rb,pil[4],pil[5],rxF[8],rxF[9],ch[8],ch[9]);*/
// ------------------------4th pilot------------------------
ch[12] = (short)(((int)pil[6]*rxF[12] - (int)pil[7]*rxF[13])>>15);
ch[13] = (short)(((int)pil[6]*rxF[13] + (int)pil[7]*rxF[12])>>15);
ch[14] = ch[12]>>1;
ch[15] = ch[13]>>1;
ch[10] += ch[14];
ch[11] += ch[15];
/* printf("rb %d: pil3 (%d,%d) x (%d,%d) = (%d,%d)\n",
rb,pil[6],pil[7],rxF[12],rxF[13],ch[12],ch[13]);*/
// ------------------------5th pilot------------------------
ch[16] = (short)(((int)pil[8]*rxF[16] - (int)pil[9]*rxF[17])>>15);
ch[17] = (short)(((int)pil[8]*rxF[17] + (int)pil[9]*rxF[16])>>15);
ch[18] = ch[16]>>1;
ch[19] = ch[17]>>1;
ch[14] += ch[18];
ch[15] += ch[19];
/* printf("rb %d: pil4 (%d,%d) x (%d,%d) = (%d,%d)\n",
rb,pil[4],pil[5],rxF[16],rxF[17],ch[16],ch[17]);*/
// ------------------------6th pilot------------------------
ch[20] = (short)(((int)pil[10]*rxF[20] - (int)pil[11]*rxF[21])>>15);
ch[21] = (short)(((int)pil[10]*rxF[21] + (int)pil[11]*rxF[20])>>15);
if ((rb<(ue->frame_parms.N_RB_DL-1))&&
(rb!=((ue->frame_parms.N_RB_DL>>1)-1))) {
ch[22] = ch[20]>>1;
ch[23] = ch[21]>>1;
ch[18] += ch[22];
ch[19] += ch[23];
} else {
ch[22] = ch[20];
ch[23] = ch[21];
ch[18] += (ch[22]>>1);
ch[19] += (ch[23]>>1);
}
/* printf("rb %d: pil5 (%d,%d) x (%d,%d) = (%d,%d)\n",
rb,pil[10],pil[11],rxF[20],rxF[21],ch[20],ch[21]);
printf("ch11 (%d,%d)\n",ch[22],ch[23]);*/
pil+=12;
ch+=24;
rxF+=24;
}
}
//*********************************************************************
else if (ue->frame_parms.N_RB_DL==25) {
//printf("Channel estimation\n");
//------------------------ loop over first 12 RBs------------------------
if (l==6) {
// ________________________First half of RBs____________________
ch+=2;
rxF+=2;
for (rb=0; rb<12; rb++) {
// ------------------------1st pilot------------------------
ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15);
ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15);
ch[2] = ch[0]>>1;
ch[3] = ch[1]>>1;
/*
printf("rb %d: pil0 (%d,%d) x (%d,%d) = (%d,%d)\n",
rb,pil[0],pil[1],rxF[0],rxF[1],ch[0],ch[1]);*/
if (rb>0) {
ch[-2] += ch[2];
ch[-1] += ch[3];
} else {
ch[-2]= ch[0];
ch[-1]= ch[1];
// ch[-2]= (ch[0]>>1)*3- ch[4];
// ch[-1]= (ch[1]>>1)*3- ch[5];
}
// ------------------------2nd pilot------------------------
ch[4] = (short)(((int)pil[2]*rxF[4] - (int)pil[3]*rxF[5])>>15);
ch[5] = (short)(((int)pil[2]*rxF[5] + (int)pil[3]*rxF[4])>>15);
ch[6] = ch[4]>>1;
ch[7] = ch[5]>>1;
ch[2] += ch[6];
ch[3] += ch[7];
/* printf("rb %d: pil1 (%d,%d) x (%d,%d) = (%d,%d)\n",
rb,pil[2],pil[3],rxF[4],rxF[5],ch[4],ch[5]);*/
// ------------------------3rd pilot------------------------
ch[8] = (short)(((int)pil[4]*rxF[8] - (int)pil[5]*rxF[9])>>15);
ch[9] = (short)(((int)pil[4]*rxF[9] + (int)pil[5]*rxF[8])>>15);
ch[10] = ch[8]>>1;
ch[11] = ch[9]>>1;
ch[6] += ch[10];
ch[7] += ch[11];
/* printf("rb %d: pil2 (%d,%d) x (%d,%d) = (%d,%d)\n",
rb,pil[4],pil[5],rxF[8],rxF[9],ch[8],ch[9]);*/
// ------------------------4th pilot------------------------
ch[12] = (short)(((int)pil[6]*rxF[12] - (int)pil[7]*rxF[13])>>15);
ch[13] = (short)(((int)pil[6]*rxF[13] + (int)pil[7]*rxF[12])>>15);
ch[14] = ch[12]>>1;
ch[15] = ch[13]>>1;
ch[10] += ch[14];
ch[11] += ch[15];
/* printf("rb %d: pil3 (%d,%d) x (%d,%d) = (%d,%d)\n",
rb,pil[6],pil[7],rxF[12],rxF[13],ch[12],ch[13]);*/
// ------------------------5th pilot------------------------
ch[16] = (short)(((int)pil[8]*rxF[16] - (int)pil[9]*rxF[17])>>15);
ch[17] = (short)(((int)pil[8]*rxF[17] + (int)pil[9]*rxF[16])>>15);
ch[18] = ch[16]>>1;
ch[19] = ch[17]>>1;
ch[14] += ch[18];
ch[15] += ch[19];
/* printf("rb %d: pil4 (%d,%d) x (%d,%d) = (%d,%d)\n",
rb,pil[4],pil[5],rxF[16],rxF[17],ch[16],ch[17]);*/
// ------------------------6th pilot------------------------
ch[20] = (short)(((int)pil[10]*rxF[20] - (int)pil[11]*rxF[21])>>15);
ch[21] = (short)(((int)pil[10]*rxF[21] + (int)pil[11]*rxF[20])>>15);
ch[22] = ch[20]>>1;
ch[23] = ch[21]>>1;
ch[18] += ch[22];
ch[19] += ch[23];
/* printf("rb %d: pil5 (%d,%d) x (%d,%d) = (%d,%d)\n",
rb,pil[10],pil[11],rxF[20],rxF[21],ch[20],ch[21]);
printf("ch11 (%d,%d)\n",ch[22],ch[23]);*/
pil+=12;
ch+=24;
rxF+=24;
}
// Middle RB
// ________________________First half of RB___________________
// ------------------------1st pilot---------------------------
chp = ch-24;
ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15);
ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15);
ch[2] = ch[0]>>1;
ch[3] = ch[1]>>1;
chp[22] += ch[2];
chp[23] += ch[3];
/* printf("rb %d: pil0 (%d,%d) x (%d,%d) = (%d,%d)\n",
rb,pil[0],pil[1],rxF[0],rxF[1],ch[0],ch[1]);*/
//printf("interp0: chp[0] (%d,%d) ch23 (%d,%d)\n",chp[22],chp[23],ch[2],ch[3]);
// ------------------------2nd pilot------------------------
ch[4] = (short)(((int)pil[2]*rxF[4] - (int)pil[3]*rxF[5])>>15);
ch[5] = (short)(((int)pil[2]*rxF[5] + (int)pil[3]*rxF[4])>>15);
ch[6] = ch[4]>>1;
ch[7] = ch[5]>>1;
ch[2] += ch[6];
ch[3] += ch[7];
/* printf("rb %d: pil1 (%d,%d) x (%d,%d) = (%d,%d)\n",
rb,pil[2],pil[3],rxF[4],rxF[5],ch[4],ch[5]);
printf("interp1: ch23 (%d,%d) \n",ch[2],ch[3]);*/
// ------------------------3rd pilot------------------------
ch[8] = (short)(((int)pil[4]*rxF[8] - (int)pil[5]*rxF[9])>>15);
ch[9] = (short)(((int)pil[4]*rxF[9] + (int)pil[5]*rxF[8])>>15);
ch[10] = ch[8]>>1;
ch[11] = ch[9]>>1;
//ch[10] = (ch[8])/3;
//ch[11] = (ch[9])/3;
ch[6] += ch[10];
ch[7] += ch[11];
/* printf("rb %d: pil2 (%d,%d) x (%d,%d) = (%d,%d)\n",
rb,pil[4],pil[5],rxF[8],rxF[9],ch[8],ch[9]);*/
// printf("Second half\n");
// ________________________Second half of RB____________________
rxF = (short *)&rxdataF[aarx][((symbol_offset+2))+subframe*(ue->frame_parms.symbols_per_tti*ue->frame_parms.ofdm_symbol_size)];
// 4th pilot
ch[12] = (short)(((int)pil[6]*rxF[0] - (int)pil[7]*rxF[1])>>15);
ch[13] = (short)(((int)pil[6]*rxF[1] + (int)pil[7]*rxF[0])>>15);
ch[14] = ch[12]>>1;
ch[15] = ch[13]>>1;
ch[10] = (ch[8]/3)+(ch[12]<<1)/3;
ch[11] = (ch[9]/3)+(ch[13]<<1)/3;
/* printf("rb %d: pil3 (%d,%d) x (%d,%d) = (%d,%d)\n",
rb,pil[6],pil[7],rxF[0],rxF[1],ch[12],ch[13]);*/
// ------------------------5th pilot------------------------
ch[16] = (short)(((int)pil[8]*rxF[4] - (int)pil[9]*rxF[5])>>15);
ch[17] = (short)(((int)pil[8]*rxF[5] + (int)pil[9]*rxF[4])>>15);
ch[18] = ch[16]>>1;
ch[19] = ch[17]>>1;
ch[14] += ch[18];
ch[15] += ch[19];
/* printf("rb %d: pil4 (%d,%d) x (%d,%d) = (%d,%d)\n",
rb,pil[4],pil[5],rxF[4],rxF[5],ch[16],ch[17]);*/
// ------------------------6th pilot------------------------
ch[20] = (short)(((int)pil[10]*rxF[8] - (int)pil[11]*rxF[9])>>15);
ch[21] = (short)(((int)pil[10]*rxF[9] + (int)pil[11]*rxF[8])>>15);
ch[22] = ch[20]>>1;
ch[23] = ch[21]>>1;
ch[18] += ch[22];
ch[19] += ch[23];
/* printf("rb %d: pil5 (%d,%d) x (%d,%d) = (%d,%d)\n",
rb,pil[10],pil[11],rxF[8],rxF[9],ch[20],ch[21]);*/
pil+=12;
ch+=24;
rxF+=12;
// ________________________Second half of RBs____________________
for (rb=0; rb<11; rb++) {
// ------------------------1st pilot---------------------------
ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15);
ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15);
ch[2] = ch[0]>>1;
ch[3] = ch[1]>>1;
/* printf("rb %d: pil0 (%d,%d) x (%d,%d) = (%d,%d)\n",
13+rb,pil[0],pil[1],rxF[0],rxF[1],ch[0],ch[1]);*/
//if (rb>0) {
ch[-2] += ch[2];
ch[-1] += ch[3];
//}
// ------------------------2nd pilot------------------------
ch[4] = (short)(((int)pil[2]*rxF[4] - (int)pil[3]*rxF[5])>>15);
ch[5] = (short)(((int)pil[2]*rxF[5] + (int)pil[3]*rxF[4])>>15);
ch[6] = ch[4]>>1;
ch[7] = ch[5]>>1;
ch[2] += ch[6];
ch[3] += ch[7];
/* printf("rb %d: pil1 (%d,%d) x (%d,%d) = (%d,%d)\n",
13+rb,pil[2],pil[3],rxF[4],rxF[5],ch[4],ch[5]);*/
// ------------------------3rd pilot------------------------
ch[8] = (short)(((int)pil[4]*rxF[8] - (int)pil[5]*rxF[9])>>15);
ch[9] = (short)(((int)pil[4]*rxF[9] + (int)pil[5]*rxF[8])>>15);
ch[10] = ch[8]>>1;
ch[11] = ch[9]>>1;
ch[6] += ch[10];
ch[7] += ch[11];
/* printf("rb %d: pil2 (%d,%d) x (%d,%d) = (%d,%d)\n",
13+rb,pil[4],pil[5],rxF[8],rxF[9],ch[8],ch[9]); */
// ------------------------4th pilot------------------------
ch[12] = (short)(((int)pil[6]*rxF[12] - (int)pil[7]*rxF[13])>>15);
ch[13] = (short)(((int)pil[6]*rxF[13] + (int)pil[7]*rxF[12])>>15);
ch[14] = ch[12]>>1;
ch[15] = ch[13]>>1;
ch[10] += ch[14];
ch[11] += ch[15];
/* printf("rb %d: pil3 (%d,%d) x (%d,%d) = (%d,%d)\n",
13+rb,pil[6],pil[7],rxF[12],rxF[13],ch[12],ch[13]);*/
// ------------------------5th pilot------------------------
ch[16] = (short)(((int)pil[8]*rxF[16] - (int)pil[9]*rxF[17])>>15);
ch[17] = (short)(((int)pil[8]*rxF[17] + (int)pil[9]*rxF[16])>>15);
ch[18] = ch[16]>>1;
ch[19] = ch[17]>>1;
ch[14] += ch[18];
ch[15] += ch[19];
/* printf("rb %d: pil4 (%d,%d) x (%d,%d) = (%d,%d)\n",
13+rb,pil[4],pil[5],rxF[16],rxF[17],ch[16],ch[17]);*/
// ------------------------6th pilot------------------------
ch[20] = (short)(((int)pil[10]*rxF[20] - (int)pil[11]*rxF[21])>>15);
ch[21] = (short)(((int)pil[10]*rxF[21] + (int)pil[11]*rxF[20])>>15);
ch[22] = ch[20]>>1;
ch[23] = ch[21]>>1;
ch[18] += ch[22];
ch[19] += ch[23];
/* printf("rb %d: pil5 (%d,%d) x (%d,%d) = (%d,%d)\n",
13+rb,pil[10],pil[11],rxF[20],rxF[21],ch[20],ch[21]);*/
pil+=12;
ch+=24;
rxF+=24;
}
// ------------------------Last PRB ---------------------------
// ------------------------1st pilot---------------------------
ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15);
ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15);
ch[2] = ch[0]>>1;
ch[3] = ch[1]>>1;
ch[-2] += ch[2];
ch[-1] += ch[3];
/* printf("rb %d: pil0 (%d,%d) x (%d,%d) = (%d,%d)\n",
13+rb,pil[0],pil[1],rxF[0],rxF[1],ch[0],ch[1]);*/
// ------------------------2nd pilot------------------------
ch[4] = (short)(((int)pil[2]*rxF[4] - (int)pil[3]*rxF[5])>>15);
ch[5] = (short)(((int)pil[2]*rxF[5] + (int)pil[3]*rxF[4])>>15);
ch[6] = ch[4]>>1;
ch[7] = ch[5]>>1;
ch[2] += ch[6];
ch[3] += ch[7];
/* printf("rb %d: pil1 (%d,%d) x (%d,%d) = (%d,%d)\n",
13+rb,pil[2],pil[3],rxF[4],rxF[5],ch[4],ch[5]); */
// ------------------------3rd pilot------------------------
ch[8] = (short)(((int)pil[4]*rxF[8] - (int)pil[5]*rxF[9])>>15);
ch[9] = (short)(((int)pil[4]*rxF[9] + (int)pil[5]*rxF[8])>>15);
ch[10] = ch[8]>>1;
ch[11] = ch[9]>>1;
ch[6] += ch[10];
ch[7] += ch[11];
/* printf("rb %d: pil2 (%d,%d) x (%d,%d) = (%d,%d)\n",
13+rb,pil[4],pil[5],rxF[8],rxF[9],ch[8],ch[9]);*/
// ------------------------4th pilot------------------------
ch[12] = (short)(((int)pil[6]*rxF[12] - (int)pil[7]*rxF[13])>>15);
ch[13] = (short)(((int)pil[6]*rxF[13] + (int)pil[7]*rxF[12])>>15);
ch[14] = ch[12]>>1;
ch[15] = ch[13]>>1;
ch[10] += ch[14];
ch[11] += ch[15];
/* printf("rb %d: pil3 (%d,%d) x (%d,%d) = (%d,%d)\n",
13+rb,pil[6],pil[7],rxF[12],rxF[13],ch[12],ch[13]);*/
// ------------------------5th pilot------------------------
ch[16] = (short)(((int)pil[8]*rxF[16] - (int)pil[9]*rxF[17])>>15);
ch[17] = (short)(((int)pil[8]*rxF[17] + (int)pil[9]*rxF[16])>>15);
ch[18] = ch[16]>>1;
ch[19] = ch[17]>>1;
ch[14] += ch[18];
ch[15] += ch[19];
/* printf("rb %d: pil4 (%d,%d) x (%d,%d) = (%d,%d)\n",
13+rb,pil[4],pil[5],rxF[16],rxF[17],ch[16],ch[17]);*/
// ------------------------6th pilot------------------------
ch[20] = (short)(((int)pil[10]*rxF[20] - (int)pil[11]*rxF[21])>>15);
ch[21] = (short)(((int)pil[10]*rxF[21] + (int)pil[11]*rxF[20])>>15);
ch[18] += ch[20]>>1;
ch[19] += ch[21]>>1;
/* printf("rb %d: pil5 (%d,%d) x (%d,%d) = (%d,%d)\n",
13+rb,pil[10],pil[11],rxF[20],rxF[21],ch[20],ch[21]); */
}
//**********************************************************************
// for l=2 and l=10
if (l!=6) {
// extrapolate last channel estimate
for (rb=0; rb<12; rb++) {
// ------------------------1st pilot---------------------------
ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15);
ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15);
ch[2] = ch[0]>>1;
ch[3] = ch[1]>>1;
ch[-2] += ch[2];
ch[-1] += ch[3];
/* printf("rb %d: pil0 (%d,%d) x (%d,%d) = (%d,%d)\n",
rb,pil[0],pil[1],rxF[0],rxF[1],ch[0],ch[1]);*/
// ------------------------2nd pilot------------------------
ch[4] = (short)(((int)pil[2]*rxF[4] - (int)pil[3]*rxF[5])>>15);
ch[5] = (short)(((int)pil[2]*rxF[5] + (int)pil[3]*rxF[4])>>15);
ch[6] = ch[4]>>1;
ch[7] = ch[5]>>1;
ch[2] += ch[6];
ch[3] += ch[7];
/* printf("rb %d: pil1 (%d,%d) x (%d,%d) = (%d,%d)\n",
rb,pil[2],pil[3],rxF[4],rxF[5],ch[4],ch[5]);*/
// ------------------------3rd pilot------------------------
ch[8] = (short)(((int)pil[4]*rxF[8] - (int)pil[5]*rxF[9])>>15);
ch[9] = (short)(((int)pil[4]*rxF[9] + (int)pil[5]*rxF[8])>>15);
ch[10] = ch[8]>>1;
ch[11] = ch[9]>>1;
ch[6] += ch[10];
ch[7] += ch[11];
/* printf("rb %d: pil2 (%d,%d) x (%d,%d) = (%d,%d)\n",
rb,pil[4],pil[5],rxF[8],rxF[9],ch[8],ch[9]);*/
// ------------------------4th pilot------------------------
ch[12] = (short)(((int)pil[6]*rxF[12] - (int)pil[7]*rxF[13])>>15);
ch[13] = (short)(((int)pil[6]*rxF[13] + (int)pil[7]*rxF[12])>>15);
ch[14] = ch[12]>>1;
ch[15] = ch[13]>>1;
ch[10] += ch[14];
ch[11] += ch[15];
/* printf("rb %d: pil3 (%d,%d) x (%d,%d) = (%d,%d)\n",
rb,pil[6],pil[7],rxF[12],rxF[13],ch[12],ch[13]);*/
// ------------------------5th pilot------------------------
ch[16] = (short)(((int)pil[8]*rxF[16] - (int)pil[9]*rxF[17])>>15);
ch[17] = (short)(((int)pil[8]*rxF[17] + (int)pil[9]*rxF[16])>>15);
ch[18] = ch[16]>>1;
ch[19] = ch[17]>>1;
ch[14] += ch[18];
ch[15] += ch[19];
/* printf("rb %d: pil4 (%d,%d) x (%d,%d) = (%d,%d)\n",
rb,pil[4],pil[5],rxF[32],rxF[33],ch[16],ch[17]);*/
// ------------------------6th pilot------------------------
ch[20] = (short)(((int)pil[10]*rxF[20] - (int)pil[11]*rxF[21])>>15);
ch[21] = (short)(((int)pil[10]*rxF[21] + (int)pil[11]*rxF[20])>>15);
ch[22] = ch[20]>>1;
ch[23] = ch[21]>>1;
ch[18] += ch[22];
ch[19] += ch[23];
/* printf("rb %d: pil5 (%d,%d) x (%d,%d) = (%d,%d)\n",
rb,pil[10],pil[11],rxF[20],rxF[21],ch[20],ch[21]);*/
pil+=12;
ch+=24;
rxF+=24;
}
// ------------------------middle PRB--------------------------
// ------------------------1st pilot---------------------------
ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15);
ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15);
ch[2] = ch[0]>>1;
ch[3] = ch[1]>>1;
/* printf("rb %d: pil0 (%d,%d) x (%d,%d) = (%d,%d)\n",
rb,pil[0],pil[1],rxF[0],rxF[1],ch[0],ch[1]);*/
ch[-2] += ch[2];
ch[-1] += ch[3];
// ------------------------2nd pilot------------------------
ch[4] = (short)(((int)pil[2]*rxF[4] - (int)pil[3]*rxF[5])>>15);
ch[5] = (short)(((int)pil[2]*rxF[5] + (int)pil[3]*rxF[4])>>15);
ch[6] = ch[4]>>1;
ch[7] = ch[5]>>1;
ch[2] += ch[6];
ch[3] += ch[7];
/* printf("rb %d: pil1 (%d,%d) x (%d,%d) = (%d,%d)\n",
rb,pil[2],pil[3],rxF[4],rxF[5],ch[4],ch[5]);*/
// ------------------------3rd pilot------------------------
ch[8] = (short)(((int)pil[4]*rxF[8] - (int)pil[5]*rxF[9])>>15);
ch[9] = (short)(((int)pil[4]*rxF[9] + (int)pil[5]*rxF[8])>>15);
ch[10] = ch[8]>>1;
ch[11] = ch[9]>>1;
ch[6] += ch[10];
ch[7] += ch[11];
/* printf("rb %d: pil2 (%d,%d) x (%d,%d) = (%d,%d)\n",
rb,pil[4],pil[5],rxF[8],rxF[9],ch[8],ch[9]);*/
// printf("Second half\n");
// ------------------------Second half of RBs---------------------//
rxF = (short *)&rxdataF[aarx][((symbol_offset+1))+subframe*(ue->frame_parms.symbols_per_tti*ue->frame_parms.ofdm_symbol_size)];
// ---------------------------------------------------------------//
// ------------------------4th pilot------------------------
ch[12] = (short)(((int)pil[6]*rxF[0] - (int)pil[7]*rxF[1])>>15);
ch[13] = (short)(((int)pil[6]*rxF[1] + (int)pil[7]*rxF[0])>>15);
ch[14] = ch[12]>>1;
ch[15] = ch[13]>>1;
ch[10] = (ch[12]/3)+(ch[8]<<1)/3;
ch[11] = (ch[13]/3)+(ch[9]<<1)/3;
/* printf("rb %d: pil3 (%d,%d) x (%d,%d) = (%d,%d)\n",
rb,pil[6],pil[7],rxF[0],rxF[1],ch[12],ch[13]);*/
// ------------------------5th pilot------------------------
ch[16] = (short)(((int)pil[8]*rxF[4] - (int)pil[9]*rxF[5])>>15);
ch[17] = (short)(((int)pil[8]*rxF[5] + (int)pil[9]*rxF[4])>>15);
ch[18] = ch[16]>>1;
ch[19] = ch[17]>>1;
ch[14] += ch[18];
ch[15] += ch[19];
/* printf("rb %d: pil4 (%d,%d) x (%d,%d) = (%d,%d)\n",
rb,pil[4],pil[5],rxF[4],rxF[5],ch[8],ch[17]);*/
// ------------------------6th pilot------------------------
ch[20] = (short)(((int)pil[10]*rxF[8] - (int)pil[11]*rxF[9])>>15);
ch[21] = (short)(((int)pil[10]*rxF[9] + (int)pil[11]*rxF[8])>>15);
ch[22] = ch[20]>>1;
ch[23] = ch[21]>>1;
ch[18] += ch[22];
ch[19] += ch[23];
/* printf("rb %d: pil5 (%d,%d) x (%d,%d) = (%d,%d)\n",
rb,pil[10],pil[11],rxF[8],rxF[9],ch[20],ch[21]);*/
pil+=12;
ch+=24;
rxF+=12;
// ________________________Second half of RBs____________________
for (rb=0; rb<11; rb++) {
// ------------------------1st pilot---------------------------
ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15);
ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15);
ch[2] = ch[0]>>1;
ch[3] = ch[1]>>1;
ch[-2] += ch[2];
ch[-1] += ch[3];
/* printf("rb %d: pil0 (%d,%d) x (%d,%d) = (%d,%d)\n",
13+rb,pil[0],pil[1],rxF[0],rxF[1],ch[0],ch[1]);*/
// ------------------------2nd pilot------------------------
ch[4] = (short)(((int)pil[2]*rxF[4] - (int)pil[3]*rxF[5])>>15);
ch[5] = (short)(((int)pil[2]*rxF[5] + (int)pil[3]*rxF[4])>>15);
ch[6] = ch[4]>>1;
ch[7] = ch[5]>>1;
ch[2] += ch[6];
ch[3] += ch[7];
/* printf("rb %d: pil1 (%d,%d) x (%d,%d) = (%d,%d)\n",
13+rb,pil[2],pil[3],rxF[4],rxF[5],ch[4],ch[5]); */
// ------------------------3rd pilot------------------------
ch[8] = (short)(((int)pil[4]*rxF[8] - (int)pil[5]*rxF[9])>>15);
ch[9] = (short)(((int)pil[4]*rxF[9] + (int)pil[5]*rxF[8])>>15);
ch[10] = ch[8]>>1;
ch[11] = ch[9]>>1;
ch[6] += ch[10];
ch[7] += ch[11];
/* printf("rb %d: pil2 (%d,%d) x (%d,%d) = (%d,%d)\n",
13+rb,pil[4],pil[5],rxF[8],rxF[9],ch[8],ch[9]);*/
// ------------------------4th pilot------------------------
ch[12] = (short)(((int)pil[6]*rxF[12] - (int)pil[7]*rxF[13])>>15);
ch[13] = (short)(((int)pil[6]*rxF[13] + (int)pil[7]*rxF[12])>>15);
ch[14] = ch[12]>>1;
ch[15] = ch[13]>>1;
ch[10] += ch[14];
ch[11] += ch[15];
/* printf("rb %d: pil3 (%d,%d) x (%d,%d) = (%d,%d)\n",
13+rb,pil[6],pil[7],rxF[12],rxF[13],ch[12],ch[13]);*/
// ------------------------5th pilot------------------------
ch[16] = (short)(((int)pil[8]*rxF[16] - (int)pil[9]*rxF[17])>>15);
ch[17] = (short)(((int)pil[8]*rxF[17] + (int)pil[9]*rxF[16])>>15);
ch[18] = ch[16]>>1;
ch[19] = ch[17]>>1;
ch[14] += ch[18];
ch[15] += ch[19];
/* printf("rb %d: pil4 (%d,%d) x (%d,%d) = (%d,%d)\n",
13+rb,pil[4],pil[5],rxF[16],rxF[17],ch[16],ch[17]);*/
// ------------------------6th pilot------------------------
ch[20] = (short)(((int)pil[10]*rxF[20] - (int)pil[11]*rxF[21])>>15);
ch[21] = (short)(((int)pil[10]*rxF[21] + (int)pil[11]*rxF[20])>>15);
ch[22] = ch[20]>>1;
ch[23] = ch[21]>>1;
ch[18] += ch[22];
ch[19] += ch[23];
/* printf("rb %d: pil5 (%d,%d) x (%d,%d) = (%d,%d)\n",
13+rb,pil[10],pil[11],rxF[20],rxF[21],ch[20],ch[21]);*/
pil+=12;
ch+=24;
rxF+=24;
}
// ------------------------Last PRB ---------------------------
// ------------------------1st pilot---------------------------
ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15);
ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15);
ch[2] = ch[0]>>1;
ch[3] = ch[1]>>1;
ch[-2] += ch[2];
ch[-1] += ch[3];
/* printf("rb %d: pil0 (%d,%d) x (%d,%d) = (%d,%d)\n",
13+rb,pil[0],pil[1],rxF[0],rxF[1],ch[0],ch[1]);*/
// ------------------------2nd pilot------------------------
ch[4] = (short)(((int)pil[2]*rxF[4] - (int)pil[3]*rxF[5])>>15);
ch[5] = (short)(((int)pil[2]*rxF[5] + (int)pil[3]*rxF[4])>>15);
ch[6] = ch[4]>>1;
ch[7] = ch[5]>>1;
ch[2] += ch[6];
ch[3] += ch[7];
/* printf("rb %d: pil1 (%d,%d) x (%d,%d) = (%d,%d)\n",
13+rb,pil[2],pil[3],rxF[4],rxF[5],ch[4],ch[5]); */
// ------------------------3rd pilot------------------------
ch[8] = (short)(((int)pil[4]*rxF[8] - (int)pil[5]*rxF[9])>>15);
ch[9] = (short)(((int)pil[4]*rxF[9] + (int)pil[5]*rxF[8])>>15);
ch[10] = ch[8]>>1;
ch[11] = ch[9]>>1;
ch[6] += ch[10];
ch[7] += ch[11];
/* printf("rb %d: pil2 (%d,%d) x (%d,%d) = (%d,%d)\n",
13+rb,pil[4],pil[5],rxF[8],rxF[9],ch[8],ch[9]);*/
// ------------------------4th pilot------------------------
ch[12] = (short)(((int)pil[6]*rxF[12] - (int)pil[7]*rxF[13])>>15);
ch[13] = (short)(((int)pil[6]*rxF[13] + (int)pil[7]*rxF[12])>>15);
ch[14] = ch[12]>>1;
ch[15] = ch[13]>>1;
ch[10] += ch[14];
ch[11] += ch[15];
/* printf("rb %d: pil3 (%d,%d) x (%d,%d) = (%d,%d)\n",
13+rb,pil[6],pil[7],rxF[12],rxF[13],ch[12],ch[13]);*/
// ------------------------5th pilot------------------------
ch[16] = (short)(((int)pil[8]*rxF[16] - (int)pil[9]*rxF[17])>>15);
ch[17] = (short)(((int)pil[8]*rxF[17] + (int)pil[9]*rxF[16])>>15);
ch[18] = ch[16]>>1;
ch[19] = ch[17]>>1;
ch[14] += ch[18];
ch[15] += ch[19];
/* printf("rb %d: pil4 (%d,%d) x (%d,%d) = (%d,%d)\n",
13+rb,pil[4],pil[5],rxF[16],rxF[17],ch[16],ch[17]);*/
// ------------------------6th pilot------------------------
ch[20] = (short)(((int)pil[10]*rxF[20] - (int)pil[11]*rxF[21])>>15);
ch[21] = (short)(((int)pil[10]*rxF[21] + (int)pil[11]*rxF[20])>>15);
ch[22]= (ch[20]>>1)*3- ch[18];
ch[23]= (ch[21]>>1)*3- ch[19];
ch[18] += ch[20]>>1;
ch[19] += ch[21]>>1;
/* printf("rb %d: pil5 (%d,%d) x (%d,%d) = (%d,%d)\n",
13+rb,pil[10],pil[11],rxF[20],rxF[21],ch[20],ch[21]);*/
}
}
//------------------------Temporal Interpolation ------------------------------
if (l==6) {
ch = (short *)&dl_ch_estimates[aarx][ch_offset];
// printf("Interpolating ch 2,6 => %d\n",ch_offset);
ch_prev = (short *)&dl_ch_estimates[aarx][2*(ue->frame_parms.ofdm_symbol_size)];
ch0 = (short *)&dl_ch_estimates[aarx][0*(ue->frame_parms.ofdm_symbol_size)];
memcpy(ch0,ch_prev,4*ue->frame_parms.ofdm_symbol_size);
ch1 = (short *)&dl_ch_estimates[aarx][1*(ue->frame_parms.ofdm_symbol_size)];
memcpy(ch1,ch_prev,4*ue->frame_parms.ofdm_symbol_size);
// 3/4 ch2 + 1/4 ch6 => ch3
multadd_complex_vector_real_scalar(ch_prev,24576,ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(ch,8192,ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size);
// 1/2 ch2 + 1/2 ch6 => ch4
multadd_complex_vector_real_scalar(ch_prev,16384,ch_prev+(4*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(ch,16384,ch_prev+(4*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size);
// 1/4 ch2 + 3/4 ch6 => ch5
multadd_complex_vector_real_scalar(ch_prev,8192,ch_prev+(6*((ue->frame_parms.ofdm_symbol_size))),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(ch,24576,ch_prev+(6*((ue->frame_parms.ofdm_symbol_size))),0,ue->frame_parms.ofdm_symbol_size);
}
if (l==10) {
ch = (short *)&dl_ch_estimates[aarx][ch_offset];
ch_prev = (short *)&dl_ch_estimates[aarx][6*(ue->frame_parms.ofdm_symbol_size)];
// 3/4 ch6 + 1/4 ch10 => ch7
multadd_complex_vector_real_scalar(ch_prev,24576,ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(ch,8192,ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size);
// 1/2 ch6 + 1/2 ch10 => ch8
multadd_complex_vector_real_scalar(ch_prev,16384,ch_prev+(4*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(ch,16384,ch_prev+(4*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size);
// 1/4 ch6 + 3/4 ch10 => ch9
multadd_complex_vector_real_scalar(ch_prev,8192,ch_prev+(6*((ue->frame_parms.ofdm_symbol_size))),1,ue->frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(ch,24576,ch_prev+(6*((ue->frame_parms.ofdm_symbol_size))),0,ue->frame_parms.ofdm_symbol_size);
// 5/4 ch10 - 1/4 ch6 => ch11
// Ch11
ch_prev = (short *)&dl_ch_estimates[aarx][10*(ue->frame_parms.ofdm_symbol_size)];
ch11 = (short *)&dl_ch_estimates[aarx][11*(ue->frame_parms.ofdm_symbol_size)];
memcpy(ch11,ch_prev,4*ue->frame_parms.ofdm_symbol_size);
}
}
// do ifft of channel estimate
/*
for (aa=0; aa<ue->frame_parms.nb_antennas_rx*ue->frame_parms.nb_antennas_tx; aa++) {
if (ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_offset][aa]) {
switch (ue->frame_parms.N_RB_DL) {
case 6:
idft128((int16_t*) &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_offset][aa][8],
(int16_t*) ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_offset][aa],
1);
break;
case 25:
idft512((int16_t*) &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_offset][aa][8],
(int16_t*) ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_offset][aa],
1);
break;
case 50:
idft1024((int16_t*) &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_offset][aa][8],
(int16_t*) ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_offset][aa],
1);
break;
case 75:
idft1536((int16_t*) &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_offset][aa][8],
(int16_t*) ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_offset][aa],
1);
break;
case 100:
idft2048((int16_t*) &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_offset][aa][8],
(int16_t*) ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_offset][aa],
1);
break;
default:
break;
}
}
}*/
return(0);
}
......@@ -451,6 +451,290 @@ void ue_rrc_measurements(PHY_VARS_UE *ue,
#endif
}
}
void ue_rrc_measurements_freq(PHY_VARS_UE *ue,
uint8_t slot,
uint8_t abstraction_flag)
{
uint8_t subframe = slot>>1;
int aarx,rb;
uint8_t pss_symb;
uint8_t sss_symb;
int32_t **rxdataF;
int16_t *rxF,*rxF_pss,*rxF_sss;
uint16_t Nid_cell = ue->frame_parms.Nid_cell;
uint8_t eNB_offset,nu,l,nushift,k;
uint16_t off;
uint8_t previous_thread_id = ue->current_thread_id[subframe]==0 ? (RX_NB_TH-1):(ue->current_thread_id[subframe]-1);
//uint8_t isPss; // indicate if this is a slot for extracting PSS
//uint8_t isSss; // indicate if this is a slot for extracting SSS
//int32_t pss_ext[4][72]; // contain the extracted 6*12 REs for mapping the PSS
//int32_t sss_ext[4][72]; // contain the extracted 6*12 REs for mapping the SSS
//int32_t (*xss_ext)[72]; // point to either pss_ext or sss_ext for common calculation
//int16_t *re,*im; // real and imag part of each 32-bit xss_ext[][] value
//LOG_I(PHY,"UE RRC MEAS Start Subframe %d Frame Type %d slot %d \n",subframe,ue->frame_parms.frame_type,slot);
for (eNB_offset = 0; eNB_offset<1+ue->measurements.n_adj_cells; eNB_offset++) {
if (eNB_offset==0) {
ue->measurements.rssi = 0;
//ue->measurements.n0_power_tot = 0;
if (abstraction_flag == 0) {
if ( ((ue->frame_parms.frame_type == FDD) && ((subframe == 0) || (subframe == 5))) ||
((ue->frame_parms.frame_type == TDD) && ((subframe == 1) || (subframe == 6)))
)
{ // FDD PSS/SSS, compute noise in DTX REs
if (ue->frame_parms.Ncp==NORMAL) {
for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
if(ue->frame_parms.frame_type == FDD)
{
rxF_sss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[aarx][(5*ue->frame_parms.ofdm_symbol_size)+subframe*(ue->frame_parms.ofdm_symbol_size*ue->frame_parms.symbols_per_tti)];
rxF_pss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[aarx][(6*ue->frame_parms.ofdm_symbol_size)+subframe*(ue->frame_parms.ofdm_symbol_size*ue->frame_parms.symbols_per_tti)];
}
else
{
rxF_sss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[previous_thread_id].rxdataF[aarx][(13*ue->frame_parms.ofdm_symbol_size)+subframe*(ue->frame_parms.ofdm_symbol_size*ue->frame_parms.symbols_per_tti)];
rxF_pss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[aarx][(2*ue->frame_parms.ofdm_symbol_size)+subframe*(ue->frame_parms.ofdm_symbol_size*ue->frame_parms.symbols_per_tti)];
}
//-ve spectrum from SSS
//+ve spectrum from SSS
ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+70]*rxF_sss[2+70])+((int32_t)rxF_sss[2+69]*rxF_sss[2+69]));
ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+68]*rxF_sss[2+68])+((int32_t)rxF_sss[2+67]*rxF_sss[2+67]));
ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+66]*rxF_sss[2+66])+((int32_t)rxF_sss[2+65]*rxF_sss[2+65]));
// ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+64]*rxF_sss[2+64])+((int32_t)rxF_sss[2+63]*rxF_sss[2+63]));
// printf("sssp32 %d\n",ue->measurements.n0_power[aarx]);
//+ve spectrum from PSS
ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[2+70]*rxF_pss[2+70])+((int32_t)rxF_pss[2+69]*rxF_pss[2+69]));
ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[2+68]*rxF_pss[2+68])+((int32_t)rxF_pss[2+67]*rxF_pss[2+67]));
ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[2+66]*rxF_pss[2+66])+((int32_t)rxF_pss[2+65]*rxF_pss[2+65]));
// ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[2+64]*rxF_pss[2+64])+((int32_t)rxF_pss[2+63]*rxF_pss[2+63]));
// printf("pss32 %d\n",ue->measurements.n0_power[aarx]); //-ve spectrum from PSS
if(ue->frame_parms.frame_type == FDD)
{
rxF_sss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[aarx][(6*ue->frame_parms.ofdm_symbol_size)+subframe*(ue->frame_parms.ofdm_symbol_size*ue->frame_parms.symbols_per_tti)];
rxF_pss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[aarx][(7*ue->frame_parms.ofdm_symbol_size)+subframe*(ue->frame_parms.ofdm_symbol_size*ue->frame_parms.symbols_per_tti)];
}
else
{
rxF_sss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[previous_thread_id].rxdataF[aarx][(14*ue->frame_parms.ofdm_symbol_size)+subframe*(ue->frame_parms.ofdm_symbol_size*ue->frame_parms.symbols_per_tti)];
rxF_pss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[aarx][(3*ue->frame_parms.ofdm_symbol_size)+subframe*(ue->frame_parms.ofdm_symbol_size*ue->frame_parms.symbols_per_tti)];
}
// ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-72]*rxF_pss[-72])+((int32_t)rxF_pss[-71]*rxF_pss[-71]));
// printf("pssm36 %d\n",ue->measurements.n0_power[aarx]);
ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-70]*rxF_pss[-70])+((int32_t)rxF_pss[-69]*rxF_pss[-69]));
ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-68]*rxF_pss[-68])+((int32_t)rxF_pss[-67]*rxF_pss[-67]));
ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-66]*rxF_pss[-66])+((int32_t)rxF_pss[-65]*rxF_pss[-65]));
ue->measurements.n0_power[aarx] = (((int32_t)rxF_sss[-70]*rxF_sss[-70])+((int32_t)rxF_sss[-69]*rxF_sss[-69]));
ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[-68]*rxF_sss[-68])+((int32_t)rxF_sss[-67]*rxF_sss[-67]));
ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[-66]*rxF_sss[-66])+((int32_t)rxF_sss[-65]*rxF_sss[-65]));
// ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-64]*rxF_pss[-64])+((int32_t)rxF_pss[-63]*rxF_pss[-63]));
// printf("pssm32 %d\n",ue->measurements.n0_power[aarx]);
ue->measurements.n0_power_dB[aarx] = (unsigned short) dB_fixed(ue->measurements.n0_power[aarx]/12);
ue->measurements.n0_power_tot /*+=*/ = ue->measurements.n0_power[aarx];
}
//LOG_I(PHY,"Subframe %d RRC UE MEAS Noise Level %d \n", subframe, ue->measurements.n0_power_tot);
ue->measurements.n0_power_tot_dB = (unsigned short) dB_fixed(ue->measurements.n0_power_tot/(12*aarx));
ue->measurements.n0_power_tot_dBm = ue->measurements.n0_power_tot_dB - ue->rx_total_gain_dB - dB_fixed(ue->frame_parms.ofdm_symbol_size);
} else {
LOG_E(PHY, "Not yet implemented: noise power calculation when prefix length = EXTENDED\n");
}
}
else if ((ue->frame_parms.frame_type == TDD) &&
((subframe == 1) || (subframe == 6))) { // TDD PSS/SSS, compute noise in DTX REs // 2016-09-29 wilson fix incorrect noise power calculation
pss_symb = 2;
sss_symb = ue->frame_parms.symbols_per_tti-1;
if (ue->frame_parms.Ncp==NORMAL) {
for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
rxdataF = ue->common_vars.common_vars_rx_data_per_thread[(ue->current_thread_id[subframe])].rxdataF;
rxF_pss = (int16_t *) &rxdataF[aarx][((pss_symb*(ue->frame_parms.ofdm_symbol_size)))+subframe*(ue->frame_parms.ofdm_symbol_size*ue->frame_parms.symbols_per_tti)];
rxdataF = ue->common_vars.common_vars_rx_data_per_thread[previous_thread_id].rxdataF;
rxF_sss = (int16_t *) &rxdataF[aarx][((sss_symb*(ue->frame_parms.ofdm_symbol_size)))+subframe*(ue->frame_parms.ofdm_symbol_size*ue->frame_parms.symbols_per_tti)];
//-ve spectrum from SSS
// printf("slot %d: SSS DTX: %d,%d, non-DTX %d,%d\n",slot,rxF_pss[-72],rxF_pss[-71],rxF_pss[-36],rxF_pss[-35]);
// ue->measurements.n0_power[aarx] = (((int32_t)rxF_pss[-72]*rxF_pss[-72])+((int32_t)rxF_pss[-71]*rxF_pss[-71]));
// printf("sssn36 %d\n",ue->measurements.n0_power[aarx]);
ue->measurements.n0_power[aarx] = (((int32_t)rxF_pss[-70]*rxF_pss[-70])+((int32_t)rxF_pss[-69]*rxF_pss[-69]));
ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-68]*rxF_pss[-68])+((int32_t)rxF_pss[-67]*rxF_pss[-67]));
ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-66]*rxF_pss[-66])+((int32_t)rxF_pss[-65]*rxF_pss[-65]));
// ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-64]*rxF_pss[-64])+((int32_t)rxF_pss[-63]*rxF_pss[-63]));
// printf("sssm32 %d\n",ue->measurements.n0_power[aarx]);
//+ve spectrum from SSS
ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+70]*rxF_sss[2+70])+((int32_t)rxF_sss[2+69]*rxF_sss[2+69]));
ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+68]*rxF_sss[2+68])+((int32_t)rxF_sss[2+67]*rxF_sss[2+67]));
ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+66]*rxF_sss[2+66])+((int32_t)rxF_sss[2+65]*rxF_sss[2+65]));
// ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+64]*rxF_sss[2+64])+((int32_t)rxF_sss[2+63]*rxF_sss[2+63]));
// printf("sssp32 %d\n",ue->measurements.n0_power[aarx]);
//+ve spectrum from PSS
ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[2+70]*rxF_pss[2+70])+((int32_t)rxF_pss[2+69]*rxF_pss[2+69]));
ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[2+68]*rxF_pss[2+68])+((int32_t)rxF_pss[2+67]*rxF_pss[2+67]));
ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[2+66]*rxF_pss[2+66])+((int32_t)rxF_pss[2+65]*rxF_pss[2+65]));
// ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[2+64]*rxF_pss[2+64])+((int32_t)rxF_pss[2+63]*rxF_pss[2+63]));
// printf("pss32 %d\n",ue->measurements.n0_power[aarx]); //-ve spectrum from PSS
rxF_pss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[aarx][(7*ue->frame_parms.ofdm_symbol_size)+subframe*(ue->frame_parms.ofdm_symbol_size*ue->frame_parms.symbols_per_tti)];
// ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-72]*rxF_pss[-72])+((int32_t)rxF_pss[-71]*rxF_pss[-71]));
// printf("pssm36 %d\n",ue->measurements.n0_power[aarx]);
ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-70]*rxF_pss[-70])+((int32_t)rxF_pss[-69]*rxF_pss[-69]));
ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-68]*rxF_pss[-68])+((int32_t)rxF_pss[-67]*rxF_pss[-67]));
ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-66]*rxF_pss[-66])+((int32_t)rxF_pss[-65]*rxF_pss[-65]));
// ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-64]*rxF_pss[-64])+((int32_t)rxF_pss[-63]*rxF_pss[-63]));
// printf("pssm32 %d\n",ue->measurements.n0_power[aarx]);
ue->measurements.n0_power_dB[aarx] = (unsigned short) dB_fixed(ue->measurements.n0_power[aarx]/12);
ue->measurements.n0_power_tot /*+=*/ = ue->measurements.n0_power[aarx];
}
ue->measurements.n0_power_tot_dB = (unsigned short) dB_fixed(ue->measurements.n0_power_tot/(12*aarx));
ue->measurements.n0_power_tot_dBm = ue->measurements.n0_power_tot_dB - ue->rx_total_gain_dB - dB_fixed(ue->frame_parms.ofdm_symbol_size);
//LOG_I(PHY,"Subframe %d RRC UE MEAS Noise Level %d \n", subframe, ue->measurements.n0_power_tot);
}
}
}
}
// recompute nushift with eNB_offset corresponding to adjacent eNB on which to perform channel estimation
// printf("[PHY][UE %d] Frame %d slot %d Doing ue_rrc_measurements rsrp/rssi (Nid_cell %d, Nid2 %d, nushift %d, eNB_offset %d)\n",ue->Mod_id,ue->frame,slot,Nid_cell,Nid2,nushift,eNB_offset);
if (eNB_offset > 0)
Nid_cell = ue->measurements.adj_cell_id[eNB_offset-1];
nushift = Nid_cell%6;
ue->measurements.rsrp[eNB_offset] = 0;
if (abstraction_flag == 0) {
// compute RSRP using symbols 0 and 4-frame_parms->Ncp
for (l=0,nu=0; l<=(4-ue->frame_parms.Ncp); l+=(4-ue->frame_parms.Ncp),nu=3) {
k = (nu + nushift)%6;
#ifdef DEBUG_MEAS_RRC
LOG_I(PHY,"[UE %d] Frame %d subframe %d Doing ue_rrc_measurements rsrp/rssi (Nid_cell %d, nushift %d, eNB_offset %d, k %d, l %d)\n",ue->Mod_id,ue->proc.proc_rxtx[subframe&1].frame_rx,subframe,Nid_cell,nushift,
eNB_offset,k,l);
#endif
for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
rxF = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[aarx][(l*ue->frame_parms.ofdm_symbol_size)+subframe*(ue->frame_parms.ofdm_symbol_size*ue->frame_parms.symbols_per_tti)];
off = (ue->frame_parms.first_carrier_offset+k)<<1;
if (l==(4-ue->frame_parms.Ncp)) {
for (rb=0; rb<ue->frame_parms.N_RB_DL; rb++) {
// printf("rb %d, off %d, off2 %d\n",rb,off,off2);
ue->measurements.rsrp[eNB_offset] += (((int32_t)(rxF[off])*rxF[off])+((int32_t)(rxF[off+1])*rxF[off+1]));
// printf("rb %d, off %d : %d\n",rb,off,((((int32_t)rxF[off])*rxF[off])+((int32_t)(rxF[off+1])*rxF[off+1])));
// if ((ue->frame_rx&0x3ff) == 0)
// printf("rb %d, off %d : %d\n",rb,off,((rxF[off]*rxF[off])+(rxF[off+1]*rxF[off+1])));
off+=12;
if (off>=(ue->frame_parms.ofdm_symbol_size<<1))
off = (1+k)<<1;
ue->measurements.rsrp[eNB_offset] += (((int32_t)(rxF[off])*rxF[off])+((int32_t)(rxF[off+1])*rxF[off+1]));
// printf("rb %d, off %d : %d\n",rb,off,(((int32_t)(rxF[off])*rxF[off])+((int32_t)(rxF[off+1])*rxF[off+1])));
/*
if ((ue->frame_rx&0x3ff) == 0)
printf("rb %d, off %d : %d\n",rb,off,((rxF[off]*rxF[off])+(rxF[off+1]*rxF[off+1])));
*/
off+=12;
if (off>=(ue->frame_parms.ofdm_symbol_size<<1))
off = (1+k)<<1;
}
/*
if ((eNB_offset==0)&&(l==0)) {
for (i=0;i<6;i++,off2+=4)
ue->measurements.rssi += ((rxF[off2]*rxF[off2])+(rxF[off2+1]*rxF[off2+1]));
if (off2==(ue->frame_parms.ofdm_symbol_size<<2))
off2=4;
for (i=0;i<6;i++,off2+=4)
ue->measurements.rssi += ((rxF[off2]*rxF[off2])+(rxF[off2+1]*rxF[off2+1]));
}
*/
// printf("slot %d, rb %d => rsrp %d, rssi %d\n",slot,rb,ue->measurements.rsrp[eNB_offset],ue->measurements.rssi);
}
}
}
// 2 RE per PRB
// ue->measurements.rsrp[eNB_offset]/=(24*ue->frame_parms.N_RB_DL);
ue->measurements.rsrp[eNB_offset]/=(2*ue->frame_parms.N_RB_DL*ue->frame_parms.ofdm_symbol_size);
// LOG_I(PHY,"eNB: %d, RSRP: %d \n",eNB_offset,ue->measurements.rsrp[eNB_offset]);
if (eNB_offset == 0) {
// ue->measurements.rssi/=(24*ue->frame_parms.N_RB_DL);
// ue->measurements.rssi*=rx_power_correction;
// ue->measurements.rssi=ue->measurements.rsrp[0]*24/2;
ue->measurements.rssi=ue->measurements.rsrp[0]*(12*ue->frame_parms.N_RB_DL);
}
if (ue->measurements.rssi>0)
ue->measurements.rsrq[eNB_offset] = 100*ue->measurements.rsrp[eNB_offset]*ue->frame_parms.N_RB_DL/ue->measurements.rssi;
else
ue->measurements.rsrq[eNB_offset] = -12000;
//((200*ue->measurements.rsrq[eNB_offset]) + ((1024-200)*100*ue->measurements.rsrp[eNB_offset]*ue->frame_parms.N_RB_DL/ue->measurements.rssi))>>10;
} else { // Do abstraction of RSRP and RSRQ
ue->measurements.rssi = ue->measurements.rx_power_avg[0];
// dummay value for the moment
ue->measurements.rsrp[eNB_offset] = -93 ;
ue->measurements.rsrq[eNB_offset] = 3;
}
#ifdef DEBUG_MEAS_RRC
// if (slot == 0) {
if (eNB_offset == 0)
LOG_I(PHY,"[UE %d] Frame %d, subframe %d RRC Measurements => rssi %3.1f dBm (digital: %3.1f dB, gain %d), N0 %d dBm\n",ue->Mod_id,
ue->proc.proc_rxtx[subframe&1].frame_rx,subframe,10*log10(ue->measurements.rssi)-ue->rx_total_gain_dB,
10*log10(ue->measurements.rssi),
ue->rx_total_gain_dB,
ue->measurements.n0_power_tot_dBm);
LOG_I(PHY,"[UE %d] Frame %d, subframe %d RRC Measurements (idx %d, Cell id %d) => rsrp: %3.1f dBm/RE (%d), rsrq: %3.1f dB\n",
ue->Mod_id,
ue->proc.proc_rxtx[subframe&1].frame_rx,subframe,eNB_offset,
(eNB_offset>0) ? ue->measurements.adj_cell_id[eNB_offset-1] : ue->frame_parms.Nid_cell,
10*log10(ue->measurements.rsrp[eNB_offset])-ue->rx_total_gain_dB,
ue->measurements.rsrp[eNB_offset],
(10*log10(ue->measurements.rsrq[eNB_offset])));
//LOG_D(PHY,"RSRP_total_dB: %3.2f \n",(dB_fixed_times10(ue->measurements.rsrp[eNB_offset])/10.0)-ue->rx_total_gain_dB-dB_fixed(ue->frame_parms.N_RB_DL*12));
//LOG_D(PHY,"RSRP_dB: %3.2f \n",(dB_fixed_times10(ue->measurements.rsrp[eNB_offset])/10.0));
//LOG_D(PHY,"gain_loss_dB: %d \n",ue->rx_total_gain_dB);
//LOG_D(PHY,"gain_fixed_dB: %d \n",dB_fixed(ue->frame_parms.N_RB_DL*12));
// }
#endif
}
}
void lte_ue_measurements(PHY_VARS_UE *ue,
......
......@@ -1109,12 +1109,481 @@ void pdcch_extract_rbs_single(int32_t **rxdataF,
}
}
}
void pdcch_extract_rbs_single_freq(int32_t **rxdataF,
int32_t **dl_ch_estimates,
int32_t **rxdataF_ext,
int32_t **dl_ch_estimates_ext,
uint8_t symbol,
uint8_t subframe,
uint32_t high_speed_flag,
LTE_DL_FRAME_PARMS *frame_parms)
{
uint16_t rb,nb_rb=0;
uint8_t i,j,aarx;
int32_t *dl_ch0,*dl_ch0_ext,*rxF,*rxF_ext;
int nushiftmod3 = frame_parms->nushift%3;
uint8_t symbol_mod;
symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
#ifdef DEBUG_DCI_DECODING
LOG_I(PHY, "extract_rbs_single: symbol_mod %d\n",symbol_mod);
#endif
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
if (high_speed_flag == 1)
dl_ch0 = &dl_ch_estimates[aarx][5+(symbol*(frame_parms->ofdm_symbol_size))];
else
dl_ch0 = &dl_ch_estimates[aarx][5];
dl_ch0_ext = &dl_ch_estimates_ext[aarx][symbol*(frame_parms->N_RB_DL*12)];
rxF_ext = &rxdataF_ext[aarx][symbol*(frame_parms->N_RB_DL*12)];
rxF = &rxdataF[aarx][(frame_parms->first_carrier_offset + (symbol*(frame_parms->ofdm_symbol_size)))+subframe*(frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti)];
if ((frame_parms->N_RB_DL&1) == 0) { // even number of RBs
for (rb=0; rb<frame_parms->N_RB_DL; rb++) {
// For second half of RBs skip DC carrier
if (rb==(frame_parms->N_RB_DL>>1)) {
rxF = &rxdataF[aarx][(1 + (symbol*(frame_parms->ofdm_symbol_size)))+subframe*(frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti)];
//dl_ch0++;
}
if (symbol_mod>0) {
memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int32_t));
for (i=0; i<12; i++) {
rxF_ext[i]=rxF[i];
}
nb_rb++;
dl_ch0_ext+=12;
rxF_ext+=12;
dl_ch0+=12;
rxF+=12;
} else {
j=0;
for (i=0; i<12; i++) {
if ((i!=nushiftmod3) &&
(i!=(nushiftmod3+3)) &&
(i!=(nushiftmod3+6)) &&
(i!=(nushiftmod3+9))) {
rxF_ext[j]=rxF[i];
// printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
dl_ch0_ext[j++]=dl_ch0[i];
// printf("ch %d => (%d,%d)\n",i,*(short *)&dl_ch0[i],*(1+(short*)&dl_ch0[i]));
}
}
nb_rb++;
dl_ch0_ext+=8;
rxF_ext+=8;
dl_ch0+=12;
rxF+=12;
}
}
} else { // Odd number of RBs
for (rb=0; rb<frame_parms->N_RB_DL>>1; rb++) {
if (symbol_mod>0) {
memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int32_t));
for (i=0; i<12; i++)
rxF_ext[i]=rxF[i];
nb_rb++;
dl_ch0_ext+=12;
rxF_ext+=12;
dl_ch0+=12;
rxF+=12;
} else {
j=0;
for (i=0; i<12; i++) {
if ((i!=nushiftmod3) &&
(i!=(nushiftmod3+3)) &&
(i!=(nushiftmod3+6)) &&
(i!=(nushiftmod3+9))) {
rxF_ext[j]=rxF[i];
// printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
dl_ch0_ext[j++]=dl_ch0[i];
// printf("ch %d => (%d,%d)\n",i,*(short *)&dl_ch0[i],*(1+(short*)&dl_ch0[i]));
}
}
nb_rb++;
dl_ch0_ext+=8;
rxF_ext+=8;
dl_ch0+=12;
rxF+=12;
}
}
// Do middle RB (around DC)
// printf("dlch_ext %d\n",dl_ch0_ext-&dl_ch_estimates_ext[aarx][0]);
if (symbol_mod==0) {
j=0;
for (i=0; i<6; i++) {
if ((i!=nushiftmod3) &&
(i!=(nushiftmod3+3))) {
dl_ch0_ext[j]=dl_ch0[i];
rxF_ext[j++]=rxF[i];
// printf("**extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j-1],*(1+(short*)&rxF_ext[j-1]));
}
}
rxF = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))+subframe*(frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti)];
for (; i<12; i++) {
if ((i!=(nushiftmod3+6)) &&
(i!=(nushiftmod3+9))) {
dl_ch0_ext[j]=dl_ch0[i];
rxF_ext[j++]=rxF[(1+i-6)];
// printf("**extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j-1],*(1+(short*)&rxF_ext[j-1]));
}
}
nb_rb++;
dl_ch0_ext+=8;
rxF_ext+=8;
dl_ch0+=12;
rxF+=7;
rb++;
} else {
for (i=0; i<6; i++) {
dl_ch0_ext[i]=dl_ch0[i];
rxF_ext[i]=rxF[i];
}
rxF = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))+subframe*(frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti)];
for (; i<12; i++) {
dl_ch0_ext[i]=dl_ch0[i];
rxF_ext[i]=rxF[(1+i-6)];
}
nb_rb++;
dl_ch0_ext+=12;
rxF_ext+=12;
dl_ch0+=12;
rxF+=7;
rb++;
}
for (; rb<frame_parms->N_RB_DL; rb++) {
if (symbol_mod > 0) {
memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int32_t));
for (i=0; i<12; i++)
rxF_ext[i]=rxF[i];
nb_rb++;
dl_ch0_ext+=12;
rxF_ext+=12;
dl_ch0+=12;
rxF+=12;
} else {
j=0;
for (i=0; i<12; i++) {
if ((i!=(nushiftmod3)) &&
(i!=(nushiftmod3+3)) &&
(i!=(nushiftmod3+6)) &&
(i!=(nushiftmod3+9))) {
rxF_ext[j]=rxF[i];
// printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
dl_ch0_ext[j++]=dl_ch0[i];
}
}
nb_rb++;
dl_ch0_ext+=8;
rxF_ext+=8;
dl_ch0+=12;
rxF+=12;
}
}
}
}
}
void pdcch_extract_rbs_dual(int32_t **rxdataF,
int32_t **dl_ch_estimates,
int32_t **rxdataF_ext,
int32_t **dl_ch_estimates_ext,
uint8_t symbol,
uint32_t high_speed_flag,
LTE_DL_FRAME_PARMS *frame_parms)
{
uint16_t rb,nb_rb=0;
uint8_t i,aarx,j;
int32_t *dl_ch0,*dl_ch0_ext,*dl_ch1,*dl_ch1_ext,*rxF,*rxF_ext;
uint8_t symbol_mod;
int nushiftmod3 = frame_parms->nushift%3;
symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
#ifdef DEBUG_DCI_DECODING
LOG_I(PHY, "extract_rbs_dual: symbol_mod %d\n",symbol_mod);
#endif
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
if (high_speed_flag==1) {
dl_ch0 = &dl_ch_estimates[aarx][5+(symbol*(frame_parms->ofdm_symbol_size))];
dl_ch1 = &dl_ch_estimates[2+aarx][5+(symbol*(frame_parms->ofdm_symbol_size))];
} else {
dl_ch0 = &dl_ch_estimates[aarx][5];
dl_ch1 = &dl_ch_estimates[2+aarx][5];
}
dl_ch0_ext = &dl_ch_estimates_ext[aarx][symbol*(frame_parms->N_RB_DL*12)];
dl_ch1_ext = &dl_ch_estimates_ext[2+aarx][symbol*(frame_parms->N_RB_DL*12)];
// printf("pdcch extract_rbs: rxF_ext pos %d\n",symbol*(frame_parms->N_RB_DL*12));
rxF_ext = &rxdataF_ext[aarx][symbol*(frame_parms->N_RB_DL*12)];
rxF = &rxdataF[aarx][(frame_parms->first_carrier_offset + (symbol*(frame_parms->ofdm_symbol_size)))];
if ((frame_parms->N_RB_DL&1) == 0) // even number of RBs
for (rb=0; rb<frame_parms->N_RB_DL; rb++) {
// For second half of RBs skip DC carrier
if (rb==(frame_parms->N_RB_DL>>1)) {
rxF = &rxdataF[aarx][(1 + (symbol*(frame_parms->ofdm_symbol_size)))];
// dl_ch0++;
//dl_ch1++;
}
if (symbol_mod>0) {
memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int32_t));
memcpy(dl_ch1_ext,dl_ch1,12*sizeof(int32_t));
/*
printf("rb %d\n",rb);
for (i=0;i<12;i++)
printf("(%d %d)",((int16_t *)dl_ch0)[i<<1],((int16_t*)dl_ch0)[1+(i<<1)]);
printf("\n");
*/
for (i=0; i<12; i++) {
rxF_ext[i]=rxF[i];
// printf("%d : (%d,%d)\n",(rxF+(2*i)-&rxdataF[aarx][( (symbol*(frame_parms->ofdm_symbol_size)))*2])/2,
// ((int16_t*)&rxF[i<<1])[0],((int16_t*)&rxF[i<<1])[0]);
}
nb_rb++;
dl_ch0_ext+=12;
dl_ch1_ext+=12;
rxF_ext+=12;
} else {
j=0;
void pdcch_extract_rbs_dual(int32_t **rxdataF,
for (i=0; i<12; i++) {
if ((i!=nushiftmod3) &&
(i!=nushiftmod3+3) &&
(i!=nushiftmod3+6) &&
(i!=nushiftmod3+9)) {
rxF_ext[j]=rxF[i];
// printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
dl_ch0_ext[j] =dl_ch0[i];
dl_ch1_ext[j++]=dl_ch1[i];
}
}
nb_rb++;
dl_ch0_ext+=8;
dl_ch1_ext+=8;
rxF_ext+=8;
}
dl_ch0+=12;
dl_ch1+=12;
rxF+=12;
}
else { // Odd number of RBs
for (rb=0; rb<frame_parms->N_RB_DL>>1; rb++) {
// printf("rb %d: %d\n",rb,rxF-&rxdataF[aarx][(symbol*(frame_parms->ofdm_symbol_size))*2]);
if (symbol_mod>0) {
memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int32_t));
memcpy(dl_ch1_ext,dl_ch1,12*sizeof(int32_t));
for (i=0; i<12; i++)
rxF_ext[i]=rxF[i];
nb_rb++;
dl_ch0_ext+=12;
dl_ch1_ext+=12;
rxF_ext+=12;
dl_ch0+=12;
dl_ch1+=12;
rxF+=12;
} else {
j=0;
for (i=0; i<12; i++) {
if ((i!=nushiftmod3) &&
(i!=nushiftmod3+3) &&
(i!=nushiftmod3+6) &&
(i!=nushiftmod3+9)) {
rxF_ext[j]=rxF[i];
// printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
dl_ch0_ext[j]=dl_ch0[i];
dl_ch1_ext[j++]=dl_ch1[i];
// printf("ch %d => (%d,%d)\n",i,*(short *)&dl_ch0[i],*(1+(short*)&dl_ch0[i]));
}
}
nb_rb++;
dl_ch0_ext+=8;
dl_ch1_ext+=8;
rxF_ext+=8;
dl_ch0+=12;
dl_ch1+=12;
rxF+=12;
}
}
// Do middle RB (around DC)
if (symbol_mod > 0) {
for (i=0; i<6; i++) {
dl_ch0_ext[i]=dl_ch0[i];
dl_ch1_ext[i]=dl_ch1[i];
rxF_ext[i]=rxF[i];
}
rxF = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))];
for (; i<12; i++) {
dl_ch0_ext[i]=dl_ch0[i];
dl_ch1_ext[i]=dl_ch1[i];
rxF_ext[i]=rxF[(1+i)];
}
nb_rb++;
dl_ch0_ext+=12;
dl_ch1_ext+=12;
rxF_ext+=12;
dl_ch0+=12;
dl_ch1+=12;
rxF+=7;
rb++;
} else {
j=0;
for (i=0; i<6; i++) {
if ((i!=nushiftmod3) &&
(i!=nushiftmod3+3)) {
dl_ch0_ext[j]=dl_ch0[i];
dl_ch1_ext[j]=dl_ch1[i];
rxF_ext[j++]=rxF[i];
// printf("**extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j-1],*(1+(short*)&rxF_ext[j-1]));
}
}
rxF = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))];
for (; i<12; i++) {
if ((i!=nushiftmod3+6) &&
(i!=nushiftmod3+9)) {
dl_ch0_ext[j]=dl_ch0[i];
dl_ch1_ext[j]=dl_ch1[i];
rxF_ext[j++]=rxF[(1+i-6)];
// printf("**extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j-1],*(1+(short*)&rxF_ext[j-1]));
}
}
nb_rb++;
dl_ch0_ext+=8;
dl_ch1_ext+=8;
rxF_ext+=8;
dl_ch0+=12;
dl_ch1+=12;
rxF+=7;
rb++;
}
for (; rb<frame_parms->N_RB_DL; rb++) {
if (symbol_mod>0) {
// printf("rb %d: %d\n",rb,rxF-&rxdataF[aarx][(symbol*(frame_parms->ofdm_symbol_size))*2]);
memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int32_t));
memcpy(dl_ch1_ext,dl_ch1,12*sizeof(int32_t));
for (i=0; i<12; i++)
rxF_ext[i]=rxF[i];
nb_rb++;
dl_ch0_ext+=12;
dl_ch1_ext+=12;
rxF_ext+=12;
dl_ch0+=12;
dl_ch1+=12;
rxF+=12;
} else {
j=0;
for (i=0; i<12; i++) {
if ((i!=nushiftmod3) &&
(i!=nushiftmod3+3) &&
(i!=nushiftmod3+6) &&
(i!=nushiftmod3+9)) {
rxF_ext[j]=rxF[i];
// printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
dl_ch0_ext[j]=dl_ch0[i];
dl_ch1_ext[j++]=dl_ch1[i];
}
}
nb_rb++;
dl_ch0_ext+=8;
dl_ch1_ext+=8;
rxF_ext+=8;
dl_ch0+=12;
dl_ch1+=12;
rxF+=12;
}
}
}
}
}
void pdcch_extract_rbs_dual_freq(int32_t **rxdataF,
int32_t **dl_ch_estimates,
int32_t **rxdataF_ext,
int32_t **dl_ch_estimates_ext,
uint8_t symbol,
uint8_t subframe,
uint32_t high_speed_flag,
LTE_DL_FRAME_PARMS *frame_parms)
{
......@@ -1147,14 +1616,14 @@ void pdcch_extract_rbs_dual(int32_t **rxdataF,
// printf("pdcch extract_rbs: rxF_ext pos %d\n",symbol*(frame_parms->N_RB_DL*12));
rxF_ext = &rxdataF_ext[aarx][symbol*(frame_parms->N_RB_DL*12)];
rxF = &rxdataF[aarx][(frame_parms->first_carrier_offset + (symbol*(frame_parms->ofdm_symbol_size)))];
rxF = &rxdataF[aarx][(frame_parms->first_carrier_offset + (symbol*(frame_parms->ofdm_symbol_size)))+subframe*(frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti)];
if ((frame_parms->N_RB_DL&1) == 0) // even number of RBs
for (rb=0; rb<frame_parms->N_RB_DL; rb++) {
// For second half of RBs skip DC carrier
if (rb==(frame_parms->N_RB_DL>>1)) {
rxF = &rxdataF[aarx][(1 + (symbol*(frame_parms->ofdm_symbol_size)))];
rxF = &rxdataF[aarx][(1 + (symbol*(frame_parms->ofdm_symbol_size)))+subframe*(frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti)];
// dl_ch0++;
//dl_ch1++;
}
......@@ -1263,7 +1732,7 @@ void pdcch_extract_rbs_dual(int32_t **rxdataF,
rxF_ext[i]=rxF[i];
}
rxF = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))];
rxF = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))+subframe*(frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti)];
for (; i<12; i++) {
dl_ch0_ext[i]=dl_ch0[i];
......@@ -1293,7 +1762,7 @@ void pdcch_extract_rbs_dual(int32_t **rxdataF,
}
}
rxF = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))];
rxF = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))+subframe*(frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti)];
for (; i<12; i++) {
if ((i!=nushiftmod3+6) &&
......@@ -1363,7 +1832,6 @@ void pdcch_extract_rbs_dual(int32_t **rxdataF,
}
}
void pdcch_channel_compensation(int32_t **rxdataF_ext,
int32_t **dl_ch_estimates_ext,
int32_t **rxdataF_comp,
......@@ -1706,6 +2174,16 @@ int32_t rx_pdcch(PHY_VARS_UE *ue,
//printf("In rx_pdcch, subframe %d, eNB_id %d, pdcch_vars %d \n",subframe,eNB_id,pdcch_vars);
// procress ofdm symbol 0
if (is_secondary_ue == 1) {
if (ue->do_ofdm_mod)
pdcch_extract_rbs_single_freq(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id+1], //add 1 to eNB_id to compensate for the shifted B/F'd pilots from the SeNB
pdcch_vars[eNB_id]->rxdataF_ext,
pdcch_vars[eNB_id]->dl_ch_estimates_ext,
0,
subframe,
high_speed_flag,
frame_parms);
else
pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id+1], //add 1 to eNB_id to compensate for the shifted B/F'd pilots from the SeNB
pdcch_vars[eNB_id]->rxdataF_ext,
......@@ -1714,6 +2192,16 @@ int32_t rx_pdcch(PHY_VARS_UE *ue,
high_speed_flag,
frame_parms);
#ifdef MU_RECEIVER
if (ue->do_ofdm_mod)
pdcch_extract_rbs_single_freq(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id_i - 1],//subtract 1 to eNB_id_i to compensate for the non-shifted pilots from the PeNB
pdcch_vars[eNB_id_i]->rxdataF_ext,//shift by two to simulate transmission from a second antenna
pdcch_vars[eNB_id_i]->dl_ch_estimates_ext,//shift by two to simulate transmission from a second antenna
0,
subframe,
high_speed_flag,
frame_parms);
else
pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id_i - 1],//subtract 1 to eNB_id_i to compensate for the non-shifted pilots from the PeNB
pdcch_vars[eNB_id_i]->rxdataF_ext,//shift by two to simulate transmission from a second antenna
......@@ -1723,6 +2211,16 @@ int32_t rx_pdcch(PHY_VARS_UE *ue,
frame_parms);
#endif //MU_RECEIVER
} else if (frame_parms->nb_antenna_ports_eNB>1) {
if (ue->do_ofdm_mod)
pdcch_extract_rbs_dual_freq(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id],
pdcch_vars[eNB_id]->rxdataF_ext,
pdcch_vars[eNB_id]->dl_ch_estimates_ext,
0,
subframe,
high_speed_flag,
frame_parms);
else
pdcch_extract_rbs_dual(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id],
pdcch_vars[eNB_id]->rxdataF_ext,
......@@ -1731,6 +2229,16 @@ int32_t rx_pdcch(PHY_VARS_UE *ue,
high_speed_flag,
frame_parms);
} else {
if (ue->do_ofdm_mod)
pdcch_extract_rbs_single_freq(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id],
pdcch_vars[eNB_id]->rxdataF_ext,
pdcch_vars[eNB_id]->dl_ch_estimates_ext,
0,
subframe,
high_speed_flag,
frame_parms);
else
pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id],
pdcch_vars[eNB_id]->rxdataF_ext,
......@@ -1890,6 +2398,16 @@ int32_t rx_pdcch(PHY_VARS_UE *ue,
// process pdcch ofdm symbol 1 and 2 if necessary
for (int s=1; s<n_pdcch_symbols; s++){
if (is_secondary_ue == 1) {
if (ue->do_ofdm_mod)
pdcch_extract_rbs_single_freq(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id+1], //add 1 to eNB_id to compensate for the shifted B/F'd pilots from the SeNB
pdcch_vars[eNB_id]->rxdataF_ext,
pdcch_vars[eNB_id]->dl_ch_estimates_ext,
s,
subframe,
high_speed_flag,
frame_parms);
else
pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id+1], //add 1 to eNB_id to compensate for the shifted B/F'd pilots from the SeNB
pdcch_vars[eNB_id]->rxdataF_ext,
......@@ -1898,6 +2416,16 @@ int32_t rx_pdcch(PHY_VARS_UE *ue,
high_speed_flag,
frame_parms);
#ifdef MU_RECEIVER
if (ue->do_ofdm_mod)
pdcch_extract_rbs_single_freq(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id_i - 1],//subtract 1 to eNB_id_i to compensate for the non-shifted pilots from the PeNB
pdcch_vars[eNB_id_i]->rxdataF_ext,//shift by two to simulate transmission from a second antenna
pdcch_vars[eNB_id_i]->dl_ch_estimates_ext,//shift by two to simulate transmission from a second antenna
s,
subframe,
high_speed_flag,
frame_parms);
else
pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id_i - 1],//subtract 1 to eNB_id_i to compensate for the non-shifted pilots from the PeNB
pdcch_vars[eNB_id_i]->rxdataF_ext,//shift by two to simulate transmission from a second antenna
......@@ -1907,6 +2435,16 @@ pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current
frame_parms);
#endif //MU_RECEIVER
} else if (frame_parms->nb_antenna_ports_eNB>1) {
if (ue->do_ofdm_mod)
pdcch_extract_rbs_dual_freq(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id],
pdcch_vars[eNB_id]->rxdataF_ext,
pdcch_vars[eNB_id]->dl_ch_estimates_ext,
s,
subframe,
high_speed_flag,
frame_parms);
else
pdcch_extract_rbs_dual(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id],
pdcch_vars[eNB_id]->rxdataF_ext,
......@@ -1915,6 +2453,16 @@ pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current
high_speed_flag,
frame_parms);
} else {
if (ue->do_ofdm_mod)
pdcch_extract_rbs_single_freq(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id],
pdcch_vars[eNB_id]->rxdataF_ext,
pdcch_vars[eNB_id]->dl_ch_estimates_ext,
s,
subframe,
high_speed_flag,
frame_parms);
else
pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id],
pdcch_vars[eNB_id]->rxdataF_ext,
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -202,6 +202,223 @@ int pbch_detection(PHY_VARS_UE *ue, runmode_t mode)
}
// now check for PHICH parameters
frame_parms->phich_config_common.phich_duration = (PHICH_DURATION_t)((ue->pbch_vars[0]->decoded_output[2]>>4)&1);
dummy = (ue->pbch_vars[0]->decoded_output[2]>>2)&3;
switch (dummy) {
case 0:
frame_parms->phich_config_common.phich_resource = oneSixth;
sprintf(phich_resource,"1/6");
break;
case 1:
frame_parms->phich_config_common.phich_resource = half;
sprintf(phich_resource,"1/2");
break;
case 2:
frame_parms->phich_config_common.phich_resource = one;
sprintf(phich_resource,"1");
break;
case 3:
frame_parms->phich_config_common.phich_resource = two;
sprintf(phich_resource,"2");
break;
default:
LOG_E(PHY,"[UE%d] Initial sync: Unknown PHICH_DURATION\n",ue->Mod_id);
return -1;
break;
}
for(int i=0; i<RX_NB_TH;i++)
{
ue->proc.proc_rxtx[i].frame_rx = (((ue->pbch_vars[0]->decoded_output[2]&3)<<6) + (ue->pbch_vars[0]->decoded_output[1]>>2))<<2;
ue->proc.proc_rxtx[i].frame_rx = (((ue->pbch_vars[0]->decoded_output[2]&3)<<6) + (ue->pbch_vars[0]->decoded_output[1]>>2))<<2;
#ifndef USER_MODE
// one frame delay
ue->proc.proc_rxtx[i].frame_rx ++;
#endif
ue->proc.proc_rxtx[i].frame_tx = ue->proc.proc_rxtx[0].frame_rx;
}
#ifdef DEBUG_INITIAL_SYNCH
LOG_I(PHY,"[UE%d] Initial sync: pbch decoded sucessfully mode1_flag %d, tx_ant %d, frame %d, N_RB_DL %d, phich_duration %d, phich_resource %s!\n",
ue->Mod_id,
frame_parms->mode1_flag,
pbch_tx_ant,
ue->proc.proc_rxtx[0].frame_rx,
frame_parms->N_RB_DL,
frame_parms->phich_config_common.phich_duration,
phich_resource); //frame_parms->phich_config_common.phich_resource);
#endif
return(0);
} else {
return(-1);
}
}
int pbch_detection_freq(PHY_VARS_UE *ue, runmode_t mode)
{
uint8_t l,pbch_decoded,frame_mod4,pbch_tx_ant,dummy;
LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
char phich_resource[6];
#ifdef DEBUG_INITIAL_SYNCH
LOG_I(PHY,"[UE%d] Initial sync: starting PBCH detection (rx_offset %d)\n",ue->Mod_id,
ue->rx_offset);
#endif
for (l=0; l<frame_parms->symbols_per_tti/2; l++) {
slot_fep_freq(ue,
l,
0,
ue->rx_offset,
0,
1);
}
for (l=0; l<frame_parms->symbols_per_tti/2; l++) {
slot_fep_freq(ue,
l,
1,
ue->rx_offset,
0,
1);
}
slot_fep_freq(ue,
0,
2,
ue->rx_offset,
0,
1);
lte_ue_measurements(ue,
ue->rx_offset,
0,
0,
0,
0);
if (ue->frame_parms.frame_type == TDD) {
ue_rrc_measurements_freq(ue,
2,
0);
}
else {
ue_rrc_measurements_freq(ue,
0,
0);
}
#ifdef DEBUG_INITIAL_SYNCH
LOG_I(PHY,"[UE %d] RX RSSI %d dBm, digital (%d, %d) dB, linear (%d, %d), avg rx power %d dB (%d lin), RX gain %d dB\n",
ue->Mod_id,
ue->measurements.rx_rssi_dBm[0] - ((ue->frame_parms.nb_antennas_rx==2) ? 3 : 0),
ue->measurements.rx_power_dB[0][0],
ue->measurements.rx_power_dB[0][1],
ue->measurements.rx_power[0][0],
ue->measurements.rx_power[0][1],
ue->measurements.rx_power_avg_dB[0],
ue->measurements.rx_power_avg[0],
ue->rx_total_gain_dB);
LOG_I(PHY,"[UE %d] N0 %d dBm digital (%d, %d) dB, linear (%d, %d), avg noise power %d dB (%d lin)\n",
ue->Mod_id,
ue->measurements.n0_power_tot_dBm,
ue->measurements.n0_power_dB[0],
ue->measurements.n0_power_dB[1],
ue->measurements.n0_power[0],
ue->measurements.n0_power[1],
ue->measurements.n0_power_avg_dB,
ue->measurements.n0_power_avg);
#endif
pbch_decoded = 0;
for (frame_mod4=0; frame_mod4<4; frame_mod4++) {
pbch_tx_ant = rx_pbch(&ue->common_vars,
ue->pbch_vars[0],
frame_parms,
0,
SISO,
ue->high_speed_flag,
frame_mod4);
if ((pbch_tx_ant>0) && (pbch_tx_ant<=2)) {
pbch_decoded = 1;
break;
}
pbch_tx_ant = rx_pbch(&ue->common_vars,
ue->pbch_vars[0],
frame_parms,
0,
ALAMOUTI,
ue->high_speed_flag,
frame_mod4);
if ((pbch_tx_ant>0) && (pbch_tx_ant<=2)) {
pbch_decoded = 1;
break;
}
}
if (pbch_decoded) {
frame_parms->nb_antenna_ports_eNB = pbch_tx_ant;
// set initial transmission mode to 1 or 2 depending on number of detected TX antennas
frame_parms->mode1_flag = (pbch_tx_ant==1);
// openair_daq_vars.dlsch_transmission_mode = (pbch_tx_ant>1) ? 2 : 1;
// flip byte endian on 24-bits for MIB
// dummy = ue->pbch_vars[0]->decoded_output[0];
// ue->pbch_vars[0]->decoded_output[0] = ue->pbch_vars[0]->decoded_output[2];
// ue->pbch_vars[0]->decoded_output[2] = dummy;
// now check for Bandwidth of Cell
dummy = (ue->pbch_vars[0]->decoded_output[2]>>5)&7;
switch (dummy) {
case 0 :
frame_parms->N_RB_DL = 6;
break;
case 1 :
frame_parms->N_RB_DL = 15;
break;
case 2 :
frame_parms->N_RB_DL = 25;
break;
case 3 :
frame_parms->N_RB_DL = 50;
break;
case 4 :
frame_parms->N_RB_DL = 75;
break;
case 5:
frame_parms->N_RB_DL = 100;
break;
default:
LOG_E(PHY,"[UE%d] Initial sync: PBCH decoding: Unknown N_RB_DL\n",ue->Mod_id);
return -1;
break;
}
// now check for PHICH parameters
frame_parms->phich_config_common.phich_duration = (PHICH_DURATION_t)((ue->pbch_vars[0]->decoded_output[2]>>4)&1);
dummy = (ue->pbch_vars[0]->decoded_output[2]>>2)&3;
......@@ -642,4 +859,120 @@ int initial_sync(PHY_VARS_UE *ue, runmode_t mode)
// exit_fun("debug exit");
return ret;
}
int initial_sync_freq(PHY_VARS_UE *ue, runmode_t mode)
{
//int32_t sync_pos,sync_pos2,sync_pos_slot;
int32_t metric_fdd_ncp=0,metric_fdd_ecp=0,metric_tdd_ncp=0,metric_tdd_ecp=0;
uint8_t phase_fdd_ncp,phase_fdd_ecp,phase_tdd_ncp,phase_tdd_ecp;
uint8_t flip_fdd_ncp,flip_fdd_ecp,flip_tdd_ncp,flip_tdd_ecp;
// uint16_t Nid_cell_fdd_ncp=0,Nid_cell_fdd_ecp=0,Nid_cell_tdd_ncp=0,Nid_cell_tdd_ecp=0;
LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
int ret=-1;
//int aarx,rx_power=0;
/*#ifdef OAI_USRP
__m128i *rxdata128;
#endif*/
// LOG_I(PHY,"**************************************************************\n");
// First try FDD normal prefix
//frame_parms->Ncp=NORMAL;
//frame_parms->frame_type=FDD;
frame_parms->frame_type=PHY_vars_eNB_g[0][0]->frame_parms.frame_type;
frame_parms->Ncp=PHY_vars_eNB_g[0][0]->frame_parms.Ncp;
//frame_parms->N_RB_DL=PHY_vars_eNB_g[0][0]->frame_parms.N_RB_DL;
// cellid
frame_parms->Nid_cell=PHY_vars_eNB_g[0][0]->frame_parms.Nid_cell;
// nushift
//rx_sss(ue,&metric_fdd_ncp,&flip_fdd_ncp,&phase_fdd_ncp);
frame_parms->nushift = frame_parms->Nid_cell%6;
// lte-gold
lte_gold(frame_parms,ue->lte_gold_table[0],frame_parms->Nid_cell);
ret=pbch_detection_freq(ue,mode);
init_frame_parms(frame_parms,1);
printf("dumping enb frame params\n");
dump_frame_parms(&PHY_vars_eNB_g[0][0]->frame_parms);
printf("dumping ue frame params\n");
dump_frame_parms(frame_parms);
//dump_frame_parms(&ue->frame_parms);
if (ret==0) { // fake first PBCH found so indicate sync to higher layers and configure frame parameters
printf("[UE%d] frame_type is %c\n",ue->Mod_id, ue->rx_offset);
//#ifdef DEBUG_INITIAL_SYNCH
LOG_I(PHY,"[UE%d] In synch, rx_offset %d samples\n",ue->Mod_id, ue->rx_offset);
//#endif
printf("[UE%d] In synch, rx_offset %d samples\n",ue->Mod_id, ue->rx_offset);
if (ue->UE_scan_carrier == 0) {
#if UE_AUTOTEST_TRACE
LOG_I(PHY,"[UE %d] AUTOTEST Cell Sync : frame = %d, rx_offset %d, freq_offset %d \n",
ue->Mod_id,
ue->proc.proc_rxtx[0].frame_rx,
ue->rx_offset,
ue->common_vars.freq_offset );
#endif
printf("[UE %d] AUTOTEST Cell Sync : frame = %d, rx_offset %d, freq_offset %d \n",
ue->Mod_id,
ue->proc.proc_rxtx[0].frame_rx,
ue->rx_offset,
ue->common_vars.freq_offset );
if (ue->mac_enabled==1) {
LOG_I(PHY,"[UE%d] Sending synch status to higher layers\n",ue->Mod_id);
//mac_resynch();
mac_xface->dl_phy_sync_success(ue->Mod_id,ue->proc.proc_rxtx[0].frame_rx,0,1);//ue->common_vars.eNb_id);
ue->UE_mode[0] = PRACH;
}
else {
ue->UE_mode[0] = PUSCH;
}
generate_pcfich_reg_mapping(frame_parms);
generate_phich_reg_mapping(frame_parms);
ue->pbch_vars[0]->pdu_errors_conseq=0;
}
LOG_I(PHY,"[UE %d] Frame %d RRC Measurements => rssi %3.1f dBm (dig %3.1f dB, gain %d), N0 %d dBm, rsrp %3.1f dBm/RE, rsrq %3.1f dB\n",ue->Mod_id,
ue->proc.proc_rxtx[0].frame_rx,
10*log10(ue->measurements.rssi)-ue->rx_total_gain_dB,
10*log10(ue->measurements.rssi),
ue->rx_total_gain_dB,
ue->measurements.n0_power_tot_dBm,
10*log10(ue->measurements.rsrp[0])-ue->rx_total_gain_dB,
(10*log10(ue->measurements.rsrq[0])));
LOG_I(PHY,"[UE %d] Frame %d MIB Information => %s, %s, NidCell %d, N_RB_DL %d, PHICH DURATION %d, PHICH RESOURCE %s, TX_ANT %d\n",
ue->Mod_id,
ue->proc.proc_rxtx[0].frame_rx,
duplex_string[ue->frame_parms.frame_type],
prefix_string[ue->frame_parms.Ncp],
ue->frame_parms.Nid_cell,
ue->frame_parms.N_RB_DL,
ue->frame_parms.phich_config_common.phich_duration,
phich_string[ue->frame_parms.phich_config_common.phich_resource],
ue->frame_parms.nb_antenna_ports_eNB);
LOG_I(PHY,"[eNB %d] Frame %d MIB Information => %s, %s, NidCell %d, N_RB_DL %d, PHICH DURATION %d, PHICH RESOURCE %s, TX_ANT %d\n",
PHY_vars_eNB_g[0][0]->Mod_id,
PHY_vars_eNB_g[0][0]->proc.proc_rxtx[0].frame_rx,
duplex_string[PHY_vars_eNB_g[0][0]->frame_parms.frame_type],
prefix_string[PHY_vars_eNB_g[0][0]->frame_parms.Ncp],
PHY_vars_eNB_g[0][0]->frame_parms.Nid_cell,
PHY_vars_eNB_g[0][0]->frame_parms.N_RB_DL,
PHY_vars_eNB_g[0][0]->frame_parms.phich_config_common.phich_duration,
phich_string[PHY_vars_eNB_g[0][0]->frame_parms.phich_config_common.phich_resource],
PHY_vars_eNB_g[0][0]->frame_parms.nb_antenna_ports_eNB);
#if defined(OAI_USRP) || defined(EXMIMO) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
LOG_I(PHY,"[UE %d] Frame %d Measured Carrier Frequency %.0f Hz (offset %d Hz)\n",
ue->Mod_id,
ue->proc.proc_rxtx[0].frame_rx,
openair0_cfg[0].rx_freq[0]-ue->common_vars.freq_offset,
ue->common_vars.freq_offset);
#endif
}
return ret;
}
......@@ -1022,14 +1022,25 @@ uint16_t rx_pbch(LTE_UE_COMMON *lte_ue_common_vars,
(((uint16_t)pbch_a[PBCH_A>>3]<<8)+pbch_a[(PBCH_A>>3)+1]);
if (crc == 0x0000)
{
printf("[pbch] 1\n");
return(1);
}
else if (crc == 0xffff)
{
printf("[pbch] 2\n");
return(2);
}
else if (crc == 0x5555)
{
printf("[pbch] 4\n");
return(4);
}
else
{
printf("[pbch] -1\n");
return(-1);
}
}
......
......@@ -390,7 +390,60 @@ void mch_extract_rbs(int **rxdataF,
}
void mch_extract_rbs_freq(int **rxdataF,
int **dl_ch_estimates,
int **rxdataF_ext,
int **dl_ch_estimates_ext,
unsigned char symbol,
unsigned char subframe,
LTE_DL_FRAME_PARMS *frame_parms)
{
int pilots=0,i,j,offset,aarx;
// printf("Extracting PMCH: symbol %d\n",symbol);
if ((symbol==2)||
(symbol==10)) {
pilots = 1;
offset = 1;
} else if (symbol==6) {
pilots = 1;
offset = 0;
}
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
if (pilots==1) {
for (i=offset,j=0; i<frame_parms->N_RB_DL*6; i+=2,j++) {
/* printf("MCH with pilots: i %d, j %d => %d,%d\n",i,j,
*(int16_t*)&rxdataF[aarx][i+frame_parms->first_carrier_offset + (symbol*frame_parms->ofdm_symbol_size)],
*(int16_t*)(1+&rxdataF[aarx][i+frame_parms->first_carrier_offset + (symbol*frame_parms->ofdm_symbol_size)]));
*/
rxdataF_ext[aarx][j+symbol*(frame_parms->N_RB_DL*12)] = rxdataF[aarx][i+frame_parms->first_carrier_offset + (symbol*frame_parms->ofdm_symbol_size)+subframe*(frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti)];
rxdataF_ext[aarx][(frame_parms->N_RB_DL*3)+j+symbol*(frame_parms->N_RB_DL*12)] = rxdataF[aarx][i+1+ (symbol*frame_parms->ofdm_symbol_size)];
dl_ch_estimates_ext[aarx][j+symbol*(frame_parms->N_RB_DL*12)+subframe*(frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti)] = dl_ch_estimates[aarx][i+(symbol*frame_parms->ofdm_symbol_size)];
dl_ch_estimates_ext[aarx][(frame_parms->N_RB_DL*3)+j+symbol*(frame_parms->N_RB_DL*12)] = dl_ch_estimates[aarx][i+(frame_parms->N_RB_DL*6)+(symbol*frame_parms->ofdm_symbol_size)];
}
} else {
memcpy((void*)&rxdataF_ext[aarx][symbol*(frame_parms->N_RB_DL*12)],
(void*)&rxdataF[aarx][frame_parms->first_carrier_offset + (symbol*frame_parms->ofdm_symbol_size)+subframe*(frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti)],
frame_parms->N_RB_DL*24);
memcpy((void*)&rxdataF_ext[aarx][(frame_parms->N_RB_DL*6) + symbol*(frame_parms->N_RB_DL*12)],
(void*)&rxdataF[aarx][1 + (symbol*frame_parms->ofdm_symbol_size)+subframe*(frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti)],
frame_parms->N_RB_DL*24);
memcpy((void*)&dl_ch_estimates_ext[aarx][symbol*(frame_parms->N_RB_DL*12)],
(void*)&dl_ch_estimates[aarx][(symbol*frame_parms->ofdm_symbol_size)],
frame_parms->N_RB_DL*48);
}
}
}
void mch_channel_level(int **dl_ch_estimates_ext,
LTE_DL_FRAME_PARMS *frame_parms,
int *avg,
......@@ -968,7 +1021,15 @@ int rx_pmch(PHY_VARS_UE *ue,
int avgs,aarx;
//printf("*********************mch: symbol %d\n",symbol);
if (ue->do_ofdm_mod)
mch_extract_rbs_freq(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id],
pdsch_vars[eNB_id]->rxdataF_ext,
pdsch_vars[eNB_id]->dl_ch_estimates_ext,
symbol,
subframe,
frame_parms);
else
mch_extract_rbs(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id],
pdsch_vars[eNB_id]->rxdataF_ext,
......
......@@ -1056,6 +1056,17 @@ uint16_t dlsch_extract_rbs_single(int32_t **rxdataF,
uint8_t subframe,
uint32_t high_speed_flag,
LTE_DL_FRAME_PARMS *frame_parms);
uint16_t dlsch_extract_rbs_single_freq(int32_t **rxdataF,
int32_t **dl_ch_estimates,
int32_t **rxdataF_ext,
int32_t **dl_ch_estimates_ext,
uint16_t pmi,
uint8_t *pmi_ext,
uint32_t *rb_alloc,
uint8_t symbol,
uint8_t subframe,
uint32_t high_speed_flag,
LTE_DL_FRAME_PARMS *frame_parms);
/** \fn dlsch_extract_rbs_dual(int32_t **rxdataF,
int32_t **dl_ch_estimates,
......@@ -1093,6 +1104,19 @@ uint16_t dlsch_extract_rbs_dual(int32_t **rxdataF,
LTE_DL_FRAME_PARMS *frame_parms,
MIMO_mode_t mimo_mode);
uint16_t dlsch_extract_rbs_dual_freq(int32_t **rxdataF,
int32_t **dl_ch_estimates,
int32_t **rxdataF_ext,
int32_t **dl_ch_estimates_ext,
uint16_t pmi,
uint8_t *pmi_ext,
uint32_t *rb_alloc,
uint8_t symbol,
uint8_t subframe,
uint32_t high_speed_flag,
LTE_DL_FRAME_PARMS *frame_parms,
MIMO_mode_t mimo_mode);
/** \fn dlsch_extract_rbs_TM7(int32_t **rxdataF,
int32_t **dl_bf_ch_estimates,
int32_t **rxdataF_ext,
......@@ -1124,6 +1148,16 @@ uint16_t dlsch_extract_rbs_TM7(int32_t **rxdataF,
uint32_t high_speed_flag,
LTE_DL_FRAME_PARMS *frame_parms);
uint16_t dlsch_extract_rbs_TM7_freq(int32_t **rxdataF,
int32_t **dl_bf_ch_estimates,
int32_t **rxdataF_ext,
int32_t **dl_bf_ch_estimates_ext,
uint32_t *rb_alloc,
uint8_t symbol,
uint8_t subframe,
uint32_t high_speed_flag,
LTE_DL_FRAME_PARMS *frame_parms);
/** \brief This function performs channel compensation (matched filtering) on the received RBs for this allocation. In addition, it computes the squared-magnitude of the channel with weightings for 16QAM/64QAM detection as well as dual-stream detection (cross-correlation)
@param rxdataF_ext Frequency-domain received signal in RBs to be demodulated
@param dl_ch_estimates_ext Frequency-domain channel estimates in RBs to be demodulated
......
......@@ -65,12 +65,25 @@ int slot_fep(PHY_VARS_UE *phy_vars_ue,
int no_prefix,
int reset_freq_est);
int slot_fep_freq(PHY_VARS_UE *phy_vars_ue,
unsigned char l,
unsigned char Ns,
int sample_offset,
int no_prefix,
int reset_freq_est);
int slot_fep_mbsfn(PHY_VARS_UE *phy_vars_ue,
unsigned char l,
int subframe,
int sample_offset,
int no_prefix);
int slot_fep_mbsfn_freq(PHY_VARS_UE *phy_vars_ue,
unsigned char l,
int subframe,
int sample_offset,
int no_prefix);
int slot_fep_ul(LTE_DL_FRAME_PARMS *frame_parms,
LTE_eNB_COMMON *eNb_common_vars,
unsigned char l,
......
......@@ -211,6 +211,222 @@ int slot_fep(PHY_VARS_UE *ue,
}
// do frequency offset estimation here!
// use channel estimates from current symbol (=ch_t) and last symbol (ch_{t-1})
#ifdef DEBUG_FEP
printf("Frequency offset estimation\n");
#endif
if (l==(4-frame_parms->Ncp)) {
#if UE_TIMING_TRACE
start_meas(&ue->dlsch_freq_offset_estimation_stats);
#endif
lte_est_freq_offset(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates[0],
frame_parms,
l,
&common_vars->freq_offset,
reset_freq_est);
#if UE_TIMING_TRACE
stop_meas(&ue->dlsch_freq_offset_estimation_stats);
#endif
}
}
}
#ifdef DEBUG_FEP
printf("slot_fep: done\n");
#endif
return(0);
}
int slot_fep_freq(PHY_VARS_UE *ue,
unsigned char l,
unsigned char Ns,
int sample_offset,
int no_prefix,
int reset_freq_est)
{
LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
LTE_UE_COMMON *common_vars = &ue->common_vars;
uint8_t eNB_id = 0;//ue_common_vars->eNb_id;
unsigned char aa;
unsigned char symbol = l+((7-frame_parms->Ncp)*(Ns&1)); ///symbol within sub-frame
//unsigned int nb_prefix_samples = (no_prefix ? 0 : frame_parms->nb_prefix_samples);
//unsigned int nb_prefix_samples0 = (no_prefix ? 0 : frame_parms->nb_prefix_samples0);
unsigned int subframe_offset;//,subframe_offset_F;
unsigned int slot_offset;
int i;
//unsigned int frame_length_samples = frame_parms->samples_per_tti * 10;
unsigned int rx_offset;
/*LTE_UE_DLSCH_t **dlsch_ue = phy_vars_ue->dlsch_ue[eNB_id];
unsigned char harq_pid = dlsch_ue[0]->current_harq_pid;
LTE_DL_UE_HARQ_t *dlsch0_harq = dlsch_ue[0]->harq_processes[harq_pid];
int uespec_pilot[9][1200];*/
/*void (*dft)(int16_t *,int16_t *, int);
int tmp_dft_in[2048] __attribute__ ((aligned (32))); // This is for misalignment issues for 6 and 15 PRBs
switch (frame_parms->ofdm_symbol_size) {
case 128:
dft = dft128;
break;
case 256:
dft = dft256;
break;
case 512:
dft = dft512;
break;
case 1024:
dft = dft1024;
break;
case 1536:
dft = dft1536;
break;
case 2048:
dft = dft2048;
break;
default:
dft = dft512;
break;
}
if (no_prefix) {
subframe_offset = frame_parms->ofdm_symbol_size * frame_parms->symbols_per_tti * (Ns>>1);
slot_offset = frame_parms->ofdm_symbol_size * (frame_parms->symbols_per_tti>>1) * (Ns%2);
} else {
subframe_offset = frame_parms->samples_per_tti * (Ns>>1);
slot_offset = (frame_parms->samples_per_tti>>1) * (Ns%2);
}*/
// subframe_offset_F = frame_parms->ofdm_symbol_size * frame_parms->symbols_per_tti * (Ns>>1);
if (l<0 || l>=7-frame_parms->Ncp) {
printf("slot_fep: l must be between 0 and %d\n",7-frame_parms->Ncp);
return(-1);
}
if (Ns<0 || Ns>=20) {
printf("slot_fep: Ns must be between 0 and 19\n");
return(-1);
}
/*for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
memset(&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],0,frame_parms->ofdm_symbol_size*sizeof(int));
rx_offset = sample_offset + slot_offset + nb_prefix_samples0 + subframe_offset - SOFFSET;
// Align with 256 bit
// rx_offset = rx_offset&0xfffffff8;
if (l==0) {
if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size))
memcpy((short *)&common_vars->rxdata[aa][frame_length_samples],
(short *)&common_vars->rxdata[aa][0],
frame_parms->ofdm_symbol_size*sizeof(int));
if ((rx_offset&7)!=0) { // if input to dft is not 256-bit aligned, issue for size 6,15 and 25 PRBs
memcpy((void *)tmp_dft_in,
(void *)&common_vars->rxdata[aa][rx_offset % frame_length_samples],
frame_parms->ofdm_symbol_size*sizeof(int));
dft((int16_t *)tmp_dft_in,
(int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
} else { // use dft input from RX buffer directly
#if UE_TIMING_TRACE
start_meas(&ue->rx_dft_stats);
#endif
dft((int16_t *)&common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
(int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
#if UE_TIMING_TRACE
stop_meas(&ue->rx_dft_stats);
#endif
}
} else {
rx_offset += (frame_parms->ofdm_symbol_size+nb_prefix_samples)*l;// +
// (frame_parms->ofdm_symbol_size+nb_prefix_samples)*(l-1);
#ifdef DEBUG_FEP
// if (ue->frame <100)
LOG_I(PHY,"slot_fep: frame %d: slot %d, symbol %d, nb_prefix_samples %d, nb_prefix_samples0 %d, slot_offset %d, subframe_offset %d, sample_offset %d,rx_offset %d, frame_length_samples %d\n", ue->proc.proc_rxtx[(Ns>>1)&1].frame_rx,Ns, symbol,
nb_prefix_samples,nb_prefix_samples0,slot_offset,subframe_offset,sample_offset,rx_offset,frame_length_samples);
#endif
if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size))
memcpy((void *)&common_vars->rxdata[aa][frame_length_samples],
(void *)&common_vars->rxdata[aa][0],
frame_parms->ofdm_symbol_size*sizeof(int));
#if UE_TIMING_TRACE
start_meas(&ue->rx_dft_stats);
#endif
if ((rx_offset&7)!=0) { // if input to dft is not 128-bit aligned, issue for size 6 and 15 PRBs
memcpy((void *)tmp_dft_in,
(void *)&common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
frame_parms->ofdm_symbol_size*sizeof(int));
dft((int16_t *)tmp_dft_in,
(int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
} else { // use dft input from RX buffer directly
dft((int16_t *)&common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
(int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
}
#if UE_TIMING_TRACE
stop_meas(&ue->rx_dft_stats);
#endif
}
#ifdef DEBUG_FEP
// if (ue->frame <100)
printf("slot_fep: frame %d: symbol %d rx_offset %d\n", ue->proc.proc_rxtx[(Ns>>1)&1].frame_rx, symbol,rx_offset);
#endif
}*/
if (ue->perfect_ce == 0) {
if ((l==0) || (l==(4-frame_parms->Ncp))) {
for (aa=0; aa<frame_parms->nb_antenna_ports_eNB; aa++) {
#ifdef DEBUG_FEP
printf("Channel estimation eNB %d, aatx %d, slot %d, symbol %d\n",eNB_id,aa,Ns,l);
#endif
#if UE_TIMING_TRACE
start_meas(&ue->dlsch_channel_estimation_stats);
#endif
lte_dl_channel_estimation_freq(ue,eNB_id,0,
Ns,
aa,
l,
symbol);
#if UE_TIMING_TRACE
stop_meas(&ue->dlsch_channel_estimation_stats);
#endif
for (i=0; i<ue->measurements.n_adj_cells; i++) {
lte_dl_channel_estimation_freq(ue,eNB_id,i+1,
Ns,
aa,
l,
symbol);
}
}
// do frequency offset estimation here!
// use channel estimates from current symbol (=ch_t) and last symbol (ch_{t-1})
#ifdef DEBUG_FEP
......
......@@ -202,3 +202,180 @@ int slot_fep_mbsfn(PHY_VARS_UE *ue,
#endif
return(0);
}
int slot_fep_mbsfn_freq(PHY_VARS_UE *ue,
unsigned char l,
int subframe,
int sample_offset,
int no_prefix)
{
LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
LTE_UE_COMMON *common_vars = &ue->common_vars;
uint8_t eNB_id = 0;//ue_common_vars->eNb_id;
unsigned char aa;
unsigned char frame_type = frame_parms->frame_type; // Frame Type: 0 - FDD, 1 - TDD;
//unsigned int nb_prefix_samples = frame_parms->ofdm_symbol_size>>2;//(no_prefix ? 0 : frame_parms->nb_prefix_samples);
//unsigned int nb_prefix_samples0 = frame_parms->ofdm_symbol_size>>2;//(no_prefix ? 0 : frame_parms->nb_prefix_samples0);
unsigned int subframe_offset;
// int i;
unsigned int frame_length_samples = frame_parms->samples_per_tti * 10;
/*void (*dft)(int16_t *,int16_t *, int);
switch (frame_parms->ofdm_symbol_size) {
case 128:
dft = dft128;
break;
case 256:
dft = dft256;
break;
case 512:
dft = dft512;
break;
case 1024:
dft = dft1024;
break;
case 1536:
dft = dft1536;
break;
case 2048:
dft = dft2048;
break;
default:
dft = dft512;
break;
}
if (no_prefix) {
subframe_offset = frame_parms->ofdm_symbol_size * frame_parms->symbols_per_tti * subframe;
} else {
subframe_offset = frame_parms->samples_per_tti * subframe;
}*/
if (l<0 || l>=12) {
msg("slot_fep_mbsfn: l must be between 0 and 11\n");
return(-1);
}
if (((subframe == 0) || (subframe == 5) || // SFn 0,4,5,9;
(subframe == 4) || (subframe == 9))
&& (frame_type==FDD) ) { //check for valid MBSFN subframe
msg("slot_fep_mbsfn: Subframe must be 1,2,3,6,7,8 for FDD, Got %d \n",subframe);
return(-1);
} else if (((subframe == 0) || (subframe == 1) || (subframe==2) || // SFn 0,4,5,9;
(subframe == 5) || (subframe == 6))
&& (frame_type==TDD) ) { //check for valid MBSFN subframe
msg("slot_fep_mbsfn: Subframe must be 3,4,7,8,9 for TDD, Got %d \n",subframe);
return(-1);
}
#ifdef DEBUG_FEP
msg("slot_fep_mbsfn: subframe %d, symbol %d, nb_prefix_samples %d, nb_prefix_samples0 %d, subframe_offset %d, sample_offset %d\n", subframe, l, nb_prefix_samples,nb_prefix_samples0,subframe_offset,
sample_offset);
#endif
/*for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
memset(&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[aa][frame_parms->ofdm_symbol_size*l],0,frame_parms->ofdm_symbol_size*sizeof(int));
if (l==0) {
#if UE_TIMING_TRACE
start_meas(&ue->rx_dft_stats);
#endif
dft((int16_t *)&common_vars->rxdata[aa][(sample_offset +
nb_prefix_samples0 +
subframe_offset -
SOFFSET) % frame_length_samples],
(int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[aa][frame_parms->ofdm_symbol_size*l],1);
#if UE_TIMING_TRACE
stop_meas(&ue->rx_dft_stats);
#endif
} else {
if ((sample_offset +
(frame_parms->ofdm_symbol_size+nb_prefix_samples0+nb_prefix_samples) +
(frame_parms->ofdm_symbol_size+nb_prefix_samples)*(l-1) +
subframe_offset-
SOFFSET) > (frame_length_samples - frame_parms->ofdm_symbol_size))
memcpy((short *)&common_vars->rxdata[aa][frame_length_samples],
(short *)&common_vars->rxdata[aa][0],
frame_parms->ofdm_symbol_size*sizeof(int));
#if UE_TIMING_TRACE
start_meas(&ue->rx_dft_stats);
#endif
dft((int16_t *)&common_vars->rxdata[aa][(sample_offset +
(frame_parms->ofdm_symbol_size+nb_prefix_samples0+nb_prefix_samples) +
(frame_parms->ofdm_symbol_size+nb_prefix_samples)*(l-1) +
subframe_offset-
SOFFSET) % frame_length_samples],
(int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[aa][frame_parms->ofdm_symbol_size*l],1);
#if UE_TIMING_TRACE
stop_meas(&ue->rx_dft_stats);
#endif
}
}*/
//if ((l==0) || (l==(4-frame_parms->Ncp))) {
// changed to invoke MBSFN channel estimation in symbols 2,6,10
if ((l==2)||(l==6)||(l==10)) {
for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
if (ue->perfect_ce == 0) {
#ifdef DEBUG_FEP
msg("Channel estimation eNB %d, aatx %d, subframe %d, symbol %d\n",eNB_id,aa,subframe,l);
#endif
lte_dl_mbsfn_channel_estimation_freq(ue,
eNB_id,
0,
subframe,
l);
/* for (i=0;i<ue->PHY_measurements.n_adj_cells;i++) {
lte_dl_mbsfn_channel_estimation(ue,
eNB_id,
i+1,
subframe,
l);
lte_dl_channel_estimation(ue,eNB_id,0,
Ns,
aa,
l,
symbol);
for (i=0;i<ue->PHY_measurements.n_adj_cells;i++) {
lte_dl_channel_estimation(ue,eNB_id,i+1,
Ns,
aa,
l,
symbol); */
// }
// do frequency offset estimation here!
// use channel estimates from current symbol (=ch_t) and last symbol (ch_{t-1})
#ifdef DEBUG_FEP
msg("Frequency offset estimation\n");
#endif
// if ((l == 0) || (l==(4-frame_parms->Ncp)))
/* if ((l==2)||(l==6)||(l==10))
lte_mbsfn_est_freq_offset(common_vars->dl_ch_estimates[0],
frame_parms,
l,
&common_vars->freq_offset); */
}
}
}
#ifdef DEBUG_FEP
msg("slot_fep_mbsfn: done\n");
#endif
return(0);
}
......@@ -74,7 +74,11 @@ int write_output(const char *fname,const char *vname,void *data,int length,int d
break;
case 16:
for (i=0; i<length<<1; i+=(2*dec)) {
fprintf(fp,"%d\t%d\t%d\n",i/2,((short *)data)[i],((short *)data)[i+1]);
}
break;
case 2: // real 32-bit
for (i=0; i<length; i+=dec) {
fprintf(fp,"%d\n",((int *)data)[i]);
......
......@@ -969,6 +969,7 @@ typedef struct {
SLIST_HEAD(ral_thresholds_gen_poll_s, ral_threshold_phy_t) ral_thresholds_gen_polled[RAL_LINK_PARAM_GEN_MAX];
SLIST_HEAD(ral_thresholds_lte_poll_s, ral_threshold_phy_t) ral_thresholds_lte_polled[RAL_LINK_PARAM_LTE_MAX];
#endif
int do_ofdm_mod;
} PHY_VARS_UE;
......
......@@ -1320,6 +1320,7 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt
for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
if (!ue->do_ofdm_mod){
if (frame_parms->Ncp == 1)
PHY_ofdm_mod(&ue->common_vars.txdataF[aa][subframe_tx*nsymb*frame_parms->ofdm_symbol_size],
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
......@@ -1385,7 +1386,7 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt
write_output("txBuff.m","txSignal",&ue->common_vars.txdata[aa][ulsch_start],frame_parms->samples_per_tti,1,1);
}
*/
}//skip time domain for frequency analysis
} //nb_antennas_tx
#if UE_TIMING_TRACE
......@@ -2620,14 +2621,26 @@ void ue_measurement_procedures(
if (l==0) {
// UE measurements on symbol 0
if (abstraction_flag==0) {
LOG_D(PHY,"Calling measurements subframe %d, rxdata %p\n",subframe_rx,ue->common_vars.rxdata);
if (ue->do_ofdm_mod){//frequency analysis
LOG_D(PHY,"Calling measurements subframe %d, thread[%d].rxdataF %p\n",subframe_rx,(slot>>1)&0x1,ue->common_vars.common_vars_rx_data_per_thread[(slot>>1)&0x1].rxdataF);
lte_ue_measurements(ue,
(subframe_rx*frame_parms->samples_per_tti+ue->rx_offset)%(frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME),
(subframe_rx == 1) ? 1 : 0,
0,
0,
subframe_rx);
}
else
{
LOG_D(PHY,"Calling measurements subframe %d, rxdata %p\n",subframe_rx,ue->common_vars.rxdata);
lte_ue_measurements(ue,
(subframe_rx*frame_parms->samples_per_tti+ue->rx_offset)%(frame_parms->samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME),
(subframe_rx == 1) ? 1 : 0,
0,
0,
subframe_rx);
}
} else {
lte_ue_measurements(ue,
0,
......@@ -2686,6 +2699,7 @@ void ue_measurement_procedures(
if (abstraction_flag == 0) {
if (ue->no_timing_correction==0)
if (!ue->do_ofdm_mod)
lte_adjust_synch(&ue->frame_parms,
ue,
eNB_id,
......@@ -2867,7 +2881,11 @@ void ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uin
int frame_rx = proc->frame_rx;
int subframe_rx = proc->subframe_rx;
printf("pbch0_before. ue->proc->frame_rx %d, ue->subframe_rx %d, enb->proc->frame_tx %d, enb->subframe_tx %d\n",ue->proc.proc_rxtx[0].frame_rx,ue->proc.proc_rxtx[0].subframe_rx,PHY_vars_eNB_g[eNB_id][0]->proc.proc_rxtx[0].frame_tx,PHY_vars_eNB_g[eNB_id][0]->proc.proc_rxtx[0].subframe_tx);
printf("pbch1_before. ue->proc->frame_rx %d, ue->subframe_rx %d, enb->proc->frame_tx %d, enb->subframe_tx %d\n",ue->proc.proc_rxtx[1].frame_rx,ue->proc.proc_rxtx[1].subframe_rx,PHY_vars_eNB_g[eNB_id][0]->proc.proc_rxtx[0].frame_tx,PHY_vars_eNB_g[eNB_id][0]->proc.proc_rxtx[0].subframe_tx);
printf("pbch0_after. ue->proc->frame_rx %d, ue->subframe_rx %d, enb->proc->frame_tx %d, enb->subframe_tx %d\n",ue->proc.proc_rxtx[0].frame_rx,ue->proc.proc_rxtx[0].subframe_rx,PHY_vars_eNB_g[0][0]->proc.proc_rxtx[0].frame_tx,PHY_vars_eNB_g[0][0]->proc.proc_rxtx[0].subframe_tx);
printf("pbch1_after. ue->proc->frame_rx %d, ue->subframe_rx %d, enb->proc->frame_tx %d, enb->subframe_tx %d\n",ue->proc.proc_rxtx[1].frame_rx,ue->proc.proc_rxtx[1].subframe_rx,PHY_vars_eNB_g[0][0]->proc.proc_rxtx[1].frame_tx,PHY_vars_eNB_g[0][0]->proc.proc_rxtx[1].subframe_tx);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PBCH_PROCEDURES, VCD_FUNCTION_IN);
pbch_phase=(frame_rx%4);
......@@ -3515,7 +3533,12 @@ void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abs
if (abstraction_flag == 0 ) {
for (l=2; l<12; l++) {
if (ue->do_ofdm_mod)
slot_fep_mbsfn(ue,
l,
subframe_rx,
0,0);//ue->rx_offset,0);
else
slot_fep_mbsfn(ue,
l,
subframe_rx,
......@@ -5063,7 +5086,11 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,
#if T_TRACER
T(T_UE_PHY_DL_TICK, T_INT(ue->Mod_id), T_INT(frame_rx%1024), T_INT(subframe_rx));
if (ue->do_ofdm_mod)
T(T_UE_PHY_INPUT_SIGNAL, T_INT(ue->Mod_id), T_INT(frame_rx%1024), T_INT(subframe_rx), T_INT(0),
T_BUFFER(&ue->common_vars.rxdata[0][subframe_rx*ue->frame_parms.ofdm_symbol_size*subframe_rx*ue->frame_parms.symbols_per_tti],
ue->frame_parms.ofdm_symbol_size*subframe_rx*ue->frame_parms.symbols_per_tti * 4));
else
T(T_UE_PHY_INPUT_SIGNAL, T_INT(ue->Mod_id), T_INT(frame_rx%1024), T_INT(subframe_rx), T_INT(0),
T_BUFFER(&ue->common_vars.rxdata[0][subframe_rx*ue->frame_parms.samples_per_tti],
ue->frame_parms.samples_per_tti * 4));
......@@ -5138,6 +5165,14 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,
start_meas(&ue->ofdm_demod_stats);
#endif
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_IN);
if (ue->do_ofdm_mod)
slot_fep_freq(ue,
l,
(subframe_rx<<1),
0,
0,
0);
else
slot_fep(ue,
l,
(subframe_rx<<1),
......@@ -5179,7 +5214,14 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,
ue_pmch_procedures(ue,proc,eNB_id,abstraction_flag);
return 0;
}
if (ue->do_ofdm_mod)
slot_fep_freq(ue,
0,
1+(subframe_rx<<1),
0,
0,
0);
else
slot_fep(ue,
0,
1+(subframe_rx<<1),
......@@ -5275,6 +5317,14 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,
start_meas(&ue->ofdm_demod_stats);
#endif
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_IN);
if (ue->do_ofdm_mod)
slot_fep_freq(ue,
l,
1+(subframe_rx<<1),
0,
0,
0);
else
slot_fep(ue,
l,
1+(subframe_rx<<1),
......@@ -5295,6 +5345,14 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,
int next_subframe_rx = (1+subframe_rx)%10;
if (subframe_select(&ue->frame_parms,next_subframe_rx) != SF_UL)
{
if (ue->do_ofdm_mod)
slot_fep_freq(ue,
0,
(next_subframe_rx<<1),
0,
0,
0);
else
slot_fep(ue,
0,
(next_subframe_rx<<1),
......
......@@ -47,3 +47,59 @@ void adc(double *r_re[2],
//printf("Adc outputs %d %e %d \n",i,((short *)output[0])[((i+output_offset)<<1)], ((i+output_offset)<<1) );
}
}
void adc_freq(double *r_re[2],
double *r_im[2],
unsigned int input_offset,
unsigned int output_offset,
unsigned int **output,
unsigned int nb_rx_antennas,
unsigned int length,
unsigned char B)
{
int i;
int aa;
double gain = (double)(1<<(B-1));
//double gain = 1.0;
for (i=0; i<length; i++) {
for (aa=0; aa<nb_rx_antennas; aa++) {
((short *)output[aa])[((i+output_offset)<<1)] = (short)(r_re[aa][i+input_offset]*gain);
((short *)output[aa])[1+((i+output_offset)<<1)] = (short)(r_im[aa][i+input_offset]*gain);
if ((r_re[aa][i+input_offset]*gain) > 30000) {
//("Adc outputs %d %e %d \n",i,((short *)output[0])[((i+output_offset)<<1)], ((i+output_offset)<<1) );
}
}
//printf("Adc outputs %d %e %d \n",i,((short *)output[0])[((i+output_offset)<<1)], ((i+output_offset)<<1) );
}
}
void adc_prach(double *r_re[2],
double *r_im[2],
unsigned int input_offset,
unsigned int output_offset,
unsigned int *output,
unsigned int nb_rx_antennas,
unsigned int length,
unsigned char B)
{
int i;
int aa;
double gain = (double)(1<<(B-1));
//double gain = 1.0;
for (i=0; i<length; i++) {
for (aa=0; aa<nb_rx_antennas; aa++) {
((short *)output)[((i+output_offset)<<1)] = (short)(r_re[aa][i+input_offset]*gain);
((short *)output)[1+((i+output_offset)<<1)] = (short)(r_im[aa][i+input_offset]*gain);
if ((r_re[aa][i+input_offset]*gain) > 30000) {
//("Adc outputs %d %e %d \n",i,((short *)output[0])[((i+output_offset)<<1)], ((i+output_offset)<<1) );
}
}
//printf("Adc outputs %d %e %d \n",i,((short *)output[0])[((i+output_offset)<<1)], ((i+output_offset)<<1) );
}
}
......@@ -126,3 +126,55 @@ double dac_fixed_gain(double *s_re[2],
return(signal_energy_fp(s_re,s_im,nb_tx_antennas,length_meas,0)/NB_RE);
}
double dac_fixed_gain_prach(double *s_re[2],
double *s_im[2],
uint32_t *input,
uint32_t input_offset,
uint32_t nb_tx_antennas,
uint32_t length,
uint32_t input_offset_meas,
uint32_t length_meas,
uint8_t B,
double txpwr_dBm,
int NB_RE)
{
int i;
int aa;
double amp,amp1;
amp = //sqrt(NB_RE)*pow(10.0,.05*txpwr_dBm)/sqrt(nb_tx_antennas); //this is amp per tx antenna
pow(10.0,.05*txpwr_dBm)/sqrt(nb_tx_antennas); //this is amp per tx antenna
amp1 = 0;
for (aa=0; aa<nb_tx_antennas; aa++) {
amp1 += sqrt((double)signal_energy((int32_t*)&input[input_offset_meas],length_meas)/NB_RE);
}
amp1/=nb_tx_antennas;
// printf("DAC: amp1 %f dB (%d,%d), tx_power %f\n",20*log10(amp1),input_offset,input_offset_meas,txpwr_dBm);
/*
if (nb_tx_antennas==2)
amp1 = AMP/2;
else if (nb_tx_antennas==4)
amp1 = ((AMP*ONE_OVER_SQRT2_Q15)>>16);
else //assume (nb_tx_antennas==1)
amp1 = ((AMP*ONE_OVER_SQRT2_Q15)>>15);
amp1 = amp1*sqrt(512.0/300.0); //account for loss due to null carriers
//printf("DL: amp1 %f dB (%d,%d), tx_power %f\n",20*log10(amp1),input_offset,input_offset_meas,txpwr_dBm);
*/
for (i=0; i<length; i++) {
for (aa=0; aa<nb_tx_antennas; aa++) {
s_re[aa][i] = amp*((double)(((short *)input))[((i+input_offset)<<1)])/amp1; ///(1<<(B-1));
s_im[aa][i] = amp*((double)(((short *)input))[((i+input_offset)<<1)+1])/amp1; ///(1<<(B-1));
}
}
// printf("ener %e\n",signal_energy_fp(s_re,s_im,nb_tx_antennas,length,0));
return(signal_energy_fp(s_re,s_im,nb_tx_antennas,length_meas,0)/NB_RE);
}
......@@ -74,6 +74,24 @@ void adc(double *r_re[2],
unsigned int length,
unsigned char B);
void adc_freq(double *r_re[2],
double *r_im[2],
unsigned int input_offset,
unsigned int output_offset,
int **output,
unsigned int nb_rx_antennas,
unsigned int length,
unsigned char B);
void adc_prach(double *r_re[2],
double *r_im[2],
unsigned int input_offset,
unsigned int output_offset,
unsigned int *output,
unsigned int nb_rx_antennas,
unsigned int length,
unsigned char B);
void dac(double *s_re[2],
double *s_im[2],
int **input,
......@@ -85,6 +103,17 @@ void dac(double *s_re[2],
unsigned int meas_length,
unsigned int meas_offset);
void dac_prach(double *s_re[2],
double *s_im[2],
int **input,
unsigned int input_offset,
unsigned int nb_tx_antennas,
unsigned int length,
double amp_dBm,
unsigned char B,
unsigned int meas_length,
unsigned int meas_offset);
double dac_fixed_gain(double *s_re[2],
double *s_im[2],
int **input,
......
......@@ -139,6 +139,108 @@ int freq_channel(channel_desc_t *desc,uint16_t nb_rb,int16_t n_samples)
return(0);
}
int init_freq_channel_prach(channel_desc_t *desc,uint16_t nb_rb,int16_t n_samples,int16_t prach_fmt,int16_t prach_prb_offset)
{
double delta_f,freq; // 90 kHz spacing
double delay;
int16_t f,f1;
uint8_t l;
int prach_samples, prach_pbr_offset_samples, max_nb_rb_samples;
if ((n_samples&1)==0) {
fprintf(stderr, "freq_channel_init: n_samples has to be odd\n");
return(-1);
}
if (nb_rb-prach_prb_offset<6) {
fprintf(stderr, "freq_channel_init: Impossible to allocate PRACH, change prach_prb_offset\n");
return(-1);
}
prach_samples = (prach_fmt<4)?864:144;
cos_lut = (double **)malloc(prach_samples*sizeof(double*));
sin_lut = (double **)malloc(prach_samples*sizeof(double*));
delta_f = (prach_fmt<4)?nb_rb*180000/((n_samples-1)*12):nb_rb*180000/((n_samples-1)*2);//1.25 khz for preamble format 1,2,3. 7.5 khz for format 4
max_nb_rb_samples = nb_rb*180000/delta_f;//7200
prach_pbr_offset_samples = (prach_prb_offset+6)*180000/delta_f;//864 if prach_prb_offset=0,7200 if prach_prb_offset=44
printf("prach_samples = %d, delta_f = %e, max_nb_rb_samples= %d, prach_pbr_offset_samples = %d\n",prach_samples,delta_f,max_nb_rb_samples,prach_pbr_offset_samples);
for (f=max_nb_rb_samples/2-prach_pbr_offset_samples,f1=0; f<max_nb_rb_samples/2-prach_pbr_offset_samples+prach_samples; f++,f1++) {//3600-864,3600-864+864|3600-7200,3600-7200+839
freq=delta_f*(double)f*1e-6;// due to the fact that delays is in mus
cos_lut[f1] = (double *)malloc((int)desc->nb_taps*sizeof(double));
sin_lut[f1] = (double *)malloc((int)desc->nb_taps*sizeof(double));
for (l=0; l<(int)desc->nb_taps; l++) {
if (desc->nb_taps==1)
delay = desc->delays[l];
else
delay = desc->delays[l]+NB_SAMPLES_CHANNEL_OFFSET/desc->sampling_rate;
cos_lut[f1][l] = cos(2*M_PI*freq*delay);
sin_lut[f1][l] = sin(2*M_PI*freq*delay);
printf("freq: %e, f1: %d, f: %d, arg_sin_cos = %e, cos () = %e, sin () =n %e)\n",freq, f1,f, 2*M_PI*freq*delay, cos_lut[f1][l], sin_lut[f1][l]);
}
}
return(0);
}
int freq_channel_prach(channel_desc_t *desc,uint16_t nb_rb,int16_t n_samples,int16_t prach_fmt,int16_t prach_prb_offset)
{
int16_t f;
uint8_t aarx,aatx,l;
double *clut,*slut;
int prach_samples;
static int freq_channel_init=0;
static int n_samples_max=0;
prach_samples = (prach_fmt<4)?864:144;
// do some error checking
// n_samples has to be a odd number because we assume the spectrum is symmetric around the DC and includes the DC
if ((n_samples&1)==0) {
fprintf(stderr, "freq_channel: n_samples has to be odd\n");
return(-1);
}
if (nb_rb-prach_prb_offset<6) {
fprintf(stderr, "freq_channel_init: Impossible to allocate PRACH, check prach_prb_offset\n");
return(-1);
}
if (freq_channel_init == 0) {
// we are initializing the lut for the largets possible n_samples=12*nb_rb+1
// if called with n_samples<12*nb_rb+1, we decimate the lut
n_samples_max=12*nb_rb+1;
if (init_freq_channel_prach(desc,nb_rb,n_samples_max,prach_fmt,prach_prb_offset)==0)
freq_channel_init=1;
else
return(-1);
}
start_meas(&desc->interp_freq);
for (f=0; f<prach_samples; f++) {
clut = cos_lut[f];
slut = sin_lut[f];
for (aarx=0; aarx<desc->nb_rx; aarx++) {
for (aatx=0; aatx<desc->nb_tx; aatx++) {
desc->chF[aarx+(aatx*desc->nb_rx)][f].x=0.0;
desc->chF[aarx+(aatx*desc->nb_rx)][f].y=0.0;
for (l=0; l<(int)desc->nb_taps; l++) {
desc->chF[aarx+(aatx*desc->nb_rx)][f].x+=(desc->a[l][aarx+(aatx*desc->nb_rx)].x*clut[l]+
desc->a[l][aarx+(aatx*desc->nb_rx)].y*slut[l]);
desc->chF[aarx+(aatx*desc->nb_rx)][f].y+=(-desc->a[l][aarx+(aatx*desc->nb_rx)].x*slut[l]+
desc->a[l][aarx+(aatx*desc->nb_rx)].y*clut[l]);
}
}
}
}
stop_meas(&desc->interp_freq);
return(0);
}
double compute_pbch_sinr(channel_desc_t *desc,
channel_desc_t *desc_i1,
......
......@@ -245,6 +245,56 @@ void multipath_channel(channel_desc_t *desc,
double *rx_sig_im[2],
uint32_t length,
uint8_t keep_channel);
/**\fn void multipath_channel_freq(channel_desc_t *desc,
double tx_sig_re[2],
double tx_sig_im[2],
double rx_sig_re[2],
double rx_sig_im[2],
uint32_t length,
uint8_t keep_channel)
\brief This function generates and applys a random frequency selective random channel model.
@param desc Pointer to channel descriptor
@param tx_sig_re input signal (real component)
@param tx_sig_im input signal (imaginary component)
@param rx_sig_re output signal (real component)
@param rx_sig_im output signal (imaginary component)
@param length Length of input signal
@param keep_channel Set to 1 to keep channel constant for null-B/F
*/
void multipath_channel_freq(channel_desc_t *desc,
double *tx_sig_re[2],
double *tx_sig_im[2],
double *rx_sig_re[2],
double *rx_sig_im[2],
uint32_t length,
uint8_t keep_channel);
/**\fn void multipath_channel_prach(channel_desc_t *desc,
double tx_sig_re[2],
double tx_sig_im[2],
double rx_sig_re[2],
double rx_sig_im[2],
uint32_t length,
uint8_t keep_channel)
\brief This function generates and applys a random frequency selective random channel model.
@param desc Pointer to channel descriptor
@param tx_sig_re input signal (real component)
@param tx_sig_im input signal (imaginary component)
@param rx_sig_re output signal (real component)
@param rx_sig_im output signal (imaginary component)
@param length Length of input signal
@param keep_channel Set to 1 to keep channel constant for null-B/F
*/
void multipath_channel_freq_test(channel_desc_t *desc,
double *tx_sig_re[2],
double *tx_sig_im[2],
double *rx_sig_re[2],
double *rx_sig_im[2],
uint32_t length,
uint8_t keep_channel);
/*
\fn double compute_pbch_sinr(channel_desc_t *desc,
channel_desc_t *desc_i1,
......
......@@ -25,6 +25,7 @@
#include <string.h>
#include "defs.h"
#include "SIMULATION/RF/defs.h"
#include "PHY/extern.h"
//#define DEBUG_CH
uint8_t multipath_channel_nosigconv(channel_desc_t *desc)
......@@ -211,5 +212,197 @@ void multipath_channel(channel_desc_t *desc,
} // i
}
#endif
void multipath_channel_freq(channel_desc_t *desc,
double *tx_sig_re[2],
double *tx_sig_im[2],
double *rx_sig_re[2],
double *rx_sig_im[2],
uint32_t length,
uint8_t keep_channel)
{
int ii,j,k,f,f2;
struct complex rx_tmp;
double path_loss = pow(10,desc->path_loss_dB/20);
int dd;
dd = abs(desc->channel_offset);
int nb_rb, n_samples, ofdm_symbol_size, symbols_per_tti;
nb_rb=PHY_vars_UE_g[0][0]->frame_parms.N_RB_DL;
n_samples=PHY_vars_UE_g[0][0]->frame_parms.N_RB_DL*12+1;
ofdm_symbol_size=length/PHY_vars_UE_g[0][0]->frame_parms.symbols_per_tti;
symbols_per_tti=length/PHY_vars_UE_g[0][0]->frame_parms.ofdm_symbol_size;
FILE *file;
file = fopen("multipath.txt","w");
#ifdef DEBUG_CH
printf("[CHANNEL_FREQ] keep = %d : path_loss = %g (%f), nb_rx %d, nb_tx %d, dd %d, len %d \n",keep_channel,path_loss,desc->path_loss_dB,desc->nb_rx,desc->nb_tx,dd,desc->channel_length);
#endif
printf("[CHANNEL_FREQ] keep = %d : path_loss = %g (%f), nb_rx %d, nb_tx %d, dd %d, len %d , symbols tti %d\n",keep_channel,path_loss,desc->path_loss_dB,desc->nb_rx,desc->nb_tx,dd,desc->channel_length,symbols_per_tti);
if (keep_channel) {
// do nothing - keep channel
} else {
random_channel(desc,0);//Find a(l)
freq_channel(desc,nb_rb,n_samples);//Find desc->chF
//freq_channel_prach(desc,nb_rb,n_samples,1,44);//Find desc->chF
}
for (k=0;k<symbols_per_tti;k++){//k = 0-13 normal cyclic prefix
f2 = 0;
for (f=0;f<ofdm_symbol_size; f++) {//f2 = 0-1023 for 10 Mhz BW
for (ii=0; ii<desc->nb_rx; ii++) {
rx_tmp.x = 0;
rx_tmp.y = 0;
if (f<=(n_samples>>1) && f>0)
{
for (j=0; j<desc->nb_tx; j++) {
//first n_samples>>1 samples of each frequency ofdm symbol out of ofdm_symbol_size
//RX_RE(k) += TX_RE(k).chF(k).x - TX_IM(k).chF(k).y
//RX_IM(k) += TX_IM(k).chF(k).x + TX_RE(k).chF(k).y
rx_tmp.x += (tx_sig_re[j][f+k*ofdm_symbol_size] * desc->chF[ii+(j*desc->nb_rx)][f+(n_samples>>1)-1].x)
-(tx_sig_im[j][f+k*ofdm_symbol_size] * desc->chF[ii+(j*desc->nb_rx)][f+(n_samples>>1)-1].y);
rx_tmp.y += (tx_sig_im[j][f+k*ofdm_symbol_size] * desc->chF[ii+(j*desc->nb_rx)][f+(n_samples>>1)-1].x)
+(tx_sig_re[j][f+k*ofdm_symbol_size] * desc->chF[ii+(j*desc->nb_rx)][f+(n_samples>>1)-1].y);
} // j
rx_sig_re[ii][f+k*ofdm_symbol_size] = rx_tmp.x*path_loss;
rx_sig_im[ii][f+k*ofdm_symbol_size] = rx_tmp.y*path_loss;
}
else if (f>=ofdm_symbol_size-(n_samples>>1))
{
for (j=0; j<desc->nb_tx; j++) {
//last n_samples>>1 samples of each frequency ofdm symbol out of ofdm_symbol_size
//RX_RE(k) += TX_RE(k).chF(k).x - TX_IM(k).chF(k).y
//RX_IM(k) += TX_IM(k).chF(k).x + TX_RE(k).chF(k).y
rx_tmp.x += (tx_sig_re[j][f+k*ofdm_symbol_size] * desc->chF[ii+(j*desc->nb_rx)][f2].x)
-(tx_sig_im[j][f+k*ofdm_symbol_size] * desc->chF[ii+(j*desc->nb_rx)][f2].y);
rx_tmp.y += (tx_sig_im[j][f+k*ofdm_symbol_size] * desc->chF[ii+(j*desc->nb_rx)][f2].x)
+(tx_sig_re[j][f+k*ofdm_symbol_size] * desc->chF[ii+(j*desc->nb_rx)][f2].y);
} // j
rx_sig_re[ii][f+k*ofdm_symbol_size] = rx_tmp.x*path_loss;
rx_sig_im[ii][f+k*ofdm_symbol_size] = rx_tmp.y*path_loss;
f2++;
}
else
{
rx_sig_re[ii][f+k*ofdm_symbol_size] = 0;
rx_sig_im[ii][f+k*ofdm_symbol_size] = 0;
}
//fprintf(file,"%d\t%d\t%d\t%e\t%e\t%e\t%e\t%e\t%e\n",f,f2,k,tx_sig_re[ii][f+k*ofdm_symbol_size],tx_sig_im[ii][f+k*ofdm_symbol_size],rx_sig_re[ii][f+k*ofdm_symbol_size],rx_sig_im[ii][f+k*ofdm_symbol_size],desc->chF[0][f].x,desc->chF[0][f].y);
//fflush(file);
//printf("number of taps%d\n",desc->channel_length);
} // ii
} // f,f2,f3
}//k
//fclose(file);
}
void multipath_channel_freq_test(channel_desc_t *desc,
double *tx_sig_re[2],
double *tx_sig_im[2],
double *rx_sig_re[2],
double *rx_sig_im[2],
uint32_t length,
uint8_t keep_channel)
{
int ii,k,f;
double path_loss = pow(10,desc->path_loss_dB/20);
int dd;
dd = abs(desc->channel_offset);
int nb_rb, n_samples, ofdm_symbol_size, symbols_per_tti;
nb_rb=PHY_vars_UE_g[0][0]->frame_parms.N_RB_DL;
n_samples=PHY_vars_UE_g[0][0]->frame_parms.N_RB_DL*12+1;
ofdm_symbol_size=length/PHY_vars_UE_g[0][0]->frame_parms.symbols_per_tti;
symbols_per_tti=length/PHY_vars_UE_g[0][0]->frame_parms.ofdm_symbol_size;
printf("[CHANNEL_FREQ] keep = %d : path_loss = %g (%f), nb_rx %d, nb_tx %d, dd %d, len %d , symbols tti %d\n",keep_channel,path_loss,desc->path_loss_dB,desc->nb_rx,desc->nb_tx,dd,desc->channel_length,symbols_per_tti);
for (k=0;k<symbols_per_tti;k++){//k = 0-13 normal cyclic prefix
for (f=0;f<ofdm_symbol_size; f++) {//f2 = 0-1024 for 10 Mhz
for (ii=0; ii<desc->nb_rx; ii++) {
{
rx_sig_re[ii][f+k*ofdm_symbol_size] = tx_sig_re[ii][f+k*ofdm_symbol_size]*path_loss;
rx_sig_im[ii][f+k*ofdm_symbol_size] = tx_sig_im[ii][f+k*ofdm_symbol_size]*path_loss;
}
} // ii
} // f
}//k
}
void multipath_channel_prach(channel_desc_t *desc,
double *tx_sig_re[2],
double *tx_sig_im[2],
double *rx_sig_re[2],
double *rx_sig_im[2],
uint32_t length,
uint8_t keep_channel)
{
LTE_DL_FRAME_PARMS* const fp = &PHY_vars_UE_g[0][0]->frame_parms;
int prach_samples;
lte_frame_type_t frame_type = PHY_vars_eNB_g[0][0]->frame_parms.frame_type;
uint8_t prach_ConfigIndex = PHY_vars_eNB_g[0][0]->frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex;
uint8_t prach_fmt = get_prach_fmt(prach_ConfigIndex,frame_type);
int n_ra_prb;
int ii,j,k,f,l;
struct complex rx_tmp;
double delta_f;
FILE *file_prach;
file_prach = fopen("multipath_prach.txt","w");
prach_samples = (prach_fmt<4)?13+839+12:3+139+2;
double path_loss = pow(10,desc->path_loss_dB/20);
int nb_rb, n_samples, ofdm_symbol_size, symbols_per_tti;
n_ra_prb = get_prach_prb_offset(fp, PHY_vars_UE_g[0][0]->prach_resources[0]->ra_TDD_map_index, PHY_vars_eNB_g[0][0]->proc.frame_prach);
nb_rb=fp->N_RB_DL;
n_samples=fp->N_RB_DL*12+1;
ofdm_symbol_size=fp->ofdm_symbol_size;
symbols_per_tti=fp->symbols_per_tti;
delta_f = (prach_fmt<4)?nb_rb*180000/((n_samples-1)*12):nb_rb*180000/((n_samples-1)*2);
printf("prach_samples %d, n_ra_prb %d, delta_f %e\n",prach_samples,get_prach_prb_offset(fp, PHY_vars_UE_g[0][0]->prach_resources[0]->ra_TDD_map_index, PHY_vars_eNB_g[0][0]->proc.frame_prach), delta_f);
#ifdef DEBUG_CH
printf("[CHANNEL_PRACH] keep = %d : path_loss = %g (%f), nb_rx %d, nb_tx %d, len %d \n",keep_channel,path_loss,desc->path_loss_dB,desc->nb_rx,desc->nb_tx,desc->channel_length);
#endif
printf("[CHANNEL_PRACH] keep = %d : path_loss = %g (%f), nb_rx %d, nb_tx %d, len %d , symbols tti %d\n",keep_channel,path_loss,desc->path_loss_dB,desc->nb_rx,desc->nb_tx,desc->channel_length,symbols_per_tti);
if (keep_channel) {
// do nothing - keep channel
} else {
random_channel(desc,0);//Find a(l)
freq_channel_prach(desc,nb_rb,n_samples,prach_fmt,n_ra_prb);//Find desc->chF
}
for (l=0;l<symbols_per_tti;l++){//0-13 normal cyclic prefix
k = (12*n_ra_prb) - 6*fp->N_RB_UL;
if (k<0)
k+=fp->ofdm_symbol_size;
k*=12;
//k+=13;
k+=1;
for (f=0;f<prach_samples; f++) {
if (k>=((prach_fmt<4)?12:2)*ofdm_symbol_size)
k=0;
rx_tmp.x = 0;
rx_tmp.y = 0;
for (ii=0; ii<desc->nb_rx; ii++) {
for (j=0; j<desc->nb_tx; j++) {
//RX_RE(k) = TX_RE(k).chF(k).x - TX_IM(k).chF(k).y
rx_tmp.x += ((tx_sig_re[ii][k+l*ofdm_symbol_size*12] * desc->chF[ii+(j*desc->nb_rx)][f].x)-(tx_sig_im[ii][k+l*ofdm_symbol_size*12] * desc->chF[ii+(j*desc->nb_rx)][f].y));
//RX_IM(k) = TX_IM(k).chF(k).x + TX_RE(k).chF(k).y
rx_tmp.y += ((tx_sig_im[ii][k+l*ofdm_symbol_size*12] * desc->chF[ii+(j*desc->nb_rx)][f].x)+(tx_sig_re[ii][k+l*ofdm_symbol_size*12] * desc->chF[ii+(j*desc->nb_rx)][f].y));
} // j
rx_sig_re[ii][k+l*ofdm_symbol_size*12] = rx_tmp.x*path_loss;
rx_sig_im[ii][k+l*ofdm_symbol_size*12] = rx_tmp.y*path_loss;
//fprintf(file_prach,"%d\t%d\t%e\t%e\t%e\t%e\t%e\t%e\n",f,k,tx_sig_re[ii][k+l*ofdm_symbol_size*12],tx_sig_im[ii][k+l*ofdm_symbol_size*12],rx_sig_re[ii][k+l*ofdm_symbol_size*12],rx_sig_im[ii][k+l*ofdm_symbol_size*12],desc->chF[0][f].x,desc->chF[0][f].y);
//fflush(file_prach);
} // ii
k++;
} // f
}//l
}
......@@ -139,7 +139,7 @@ eNBs =
////////// MME parameters:
mme_ip_address = ( { ipv4 = "192.168.12.11";
mme_ip_address = ( { ipv4 = "172.24.11.201";
ipv6 = "192:168:30::17";
active = "yes";
preference = "ipv4";
......@@ -149,18 +149,18 @@ eNBs =
NETWORK_INTERFACES :
{
ENB_INTERFACE_NAME_FOR_S1_MME = "eth3";
ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.215/24";
ENB_INTERFACE_NAME_FOR_S1_MME = "eth0";
ENB_IPV4_ADDRESS_FOR_S1_MME = "172.24.10.219/24";
ENB_INTERFACE_NAME_FOR_S1U = "eth3";
ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.215/24";
ENB_IPV4_ADDRESS_FOR_S1U = "172.24.10.219/24";
ENB_PORT_FOR_S1U = 2152; # Spec 2152
};
rrh_gw_config = (
{
local_if_name = "lo";
remote_address = "127.0.0.2";
local_address = "127.0.0.1";
local_if_name = "eth0";
remote_address = "192.168.12.170";
local_address = "192.168.12.171";
local_port = 50000; #for raw option local port must be the same to remote
remote_port = 50000;
rrh_gw_active = "yes";
......
......@@ -1074,7 +1074,144 @@ void rx_rf(PHY_VARS_eNB *eNB,int *frame,int *subframe) {
}
void rx_rf_freq(PHY_VARS_eNB *eNB,int *frame,int *subframe) {
eNB_proc_t *proc = &eNB->proc;
LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
void *rxp_freq[fp->nb_antennas_rx],*txp_freq[fp->nb_antennas_tx];
unsigned int rxs_freq,txs_freq;
int i;
int tx_sfoffset = (eNB->single_thread_flag == 1) ? 3 : 2;
openair0_timestamp ts,old_ts;
if (proc->first_rx==0) {
// Transmit TX buffer based on timestamp from RX
// printf("trx_write -> USRP TS %llu (sf %d)\n", (proc->timestamp_rx+(3*fp->samples_per_tti)),(proc->subframe_rx+2)%10);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (proc->timestamp_rx+(tx_sfoffset*fp->ofdm_symbol_size*fp->symbols_per_tti))&0xffffffff );
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 );
// prepare tx buffer pointers
lte_subframe_t SF_type = subframe_select(fp,(proc->subframe_rx%10));
lte_subframe_t prevSF_type = subframe_select(fp,(proc->subframe_rx+9)%10);
lte_subframe_t nextSF_type = subframe_select(fp,(proc->subframe_rx+1)%10);
printf("[lte-enb]frame %d, subframe %d\n",*frame,*subframe);
if ((SF_type == SF_DL) ||
(SF_type == SF_S)) {
for (i=0; i<fp->nb_antennas_tx; i++)
txp_freq[i] = (void*)&eNB->common_vars.txdataF[0][i][proc->subframe_rx*fp->ofdm_symbol_size*fp->symbols_per_tti];
int siglen=fp->ofdm_symbol_size*fp->symbols_per_tti,flags=1;
if (SF_type == SF_S) {
siglen = fp->dl_symbols_in_S_subframe*(fp->ofdm_symbol_size);
printf("siglen ->%d\n",siglen);
flags=3; // end of burst
}
if ((fp->frame_type == TDD) &&
(SF_type == SF_DL)&&
(prevSF_type == SF_UL) &&
(nextSF_type == SF_DL))
flags = 2; // start of burst
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)
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_WRITE_FLAGS,flags);
txs_freq = eNB->rfdevice.trx_write_func(&eNB->rfdevice,
proc->timestamp_rx+(tx_sfoffset*fp->ofdm_symbol_size*fp->symbols_per_tti),
txp_freq,
siglen,
fp->nb_antennas_tx,
flags);
clock_gettime( CLOCK_MONOTONIC, &end_rf);
end_rf_ts = proc->timestamp_rx+(tx_sfoffset*fp->ofdm_symbol_size*fp->symbols_per_tti);
if (recv_if_count != 0 ) {
recv_if_count = recv_if_count-1;
LOG_D(HW,"[From Timestamp %"PRId64" to Timestamp %"PRId64"] RTT_RF: %"PRId64"; RTT_RF\n", start_rf_prev_ts, end_rf_ts, clock_difftime_ns(start_rf_prev, end_rf));
LOG_D(HW,"[From Timestamp %"PRId64" to Timestamp %"PRId64"] RTT_RF: %"PRId64"; RTT_RF\n",start_rf_prev2_ts, end_rf_ts, clock_difftime_ns(start_rf_prev2, end_rf));
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 );
if (txs_freq != siglen) {
LOG_E(PHY,"TX : Timeout (sent %d/%d)\n",txs_freq, fp->ofdm_symbol_size*fp->symbols_per_tti);
exit_fun( "problem transmitting frequency samples" );
}
}
}
for (i=0; i<fp->nb_antennas_rx; i++)
rxp_freq[i] = (void*)&eNB->common_vars.rxdataF[0][i][*subframe*fp->ofdm_symbol_size*fp->symbols_per_tti];
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 1 );
old_ts = proc->timestamp_rx;
rxs_freq = eNB->rfdevice.trx_read_func(&eNB->rfdevice,
&ts,
rxp_freq,
fp->ofdm_symbol_size*fp->symbols_per_tti,
fp->nb_antennas_rx);
start_rf_prev2= start_rf_prev;
start_rf_prev2_ts= start_rf_prev_ts;
start_rf_prev = start_rf_new;
start_rf_prev_ts = start_rf_new_ts;
clock_gettime( CLOCK_MONOTONIC, &start_rf_new);
start_rf_new_ts = ts;
LOG_D(PHY,"rx_rf_freq: first_rx %d received ts %"PRId64" (sptti %d)\n",proc->first_rx,ts,fp->ofdm_symbol_size*fp->symbols_per_tti);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 );
proc->timestamp_rx = ts-eNB->ts_offset;
if (rxs_freq != fp->ofdm_symbol_size*fp->symbols_per_tti)
LOG_E(PHY,"rx_rf_freq: Asked for %d samples, got %d from USRP\n",fp->ofdm_symbol_size*fp->symbols_per_tti,rxs_freq);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 );
if (proc->first_rx == 1) {
eNB->ts_offset = proc->timestamp_rx;
proc->timestamp_rx=0;
}
else {
if (proc->timestamp_rx - old_ts != fp->ofdm_symbol_size*fp->symbols_per_tti) {
LOG_I(PHY,"rx_rf_freq: rfdevice timing drift of %"PRId64" samples (ts_off %"PRId64")\n",proc->timestamp_rx - old_ts - fp->ofdm_symbol_size*fp->symbols_per_tti,eNB->ts_offset);
eNB->ts_offset += (proc->timestamp_rx - old_ts - fp->ofdm_symbol_size*fp->symbols_per_tti);
proc->timestamp_rx = ts-eNB->ts_offset;
}
}
proc->frame_rx = (proc->timestamp_rx / (fp->ofdm_symbol_size*fp->symbols_per_tti*10))&1023;
proc->subframe_rx = (proc->timestamp_rx/(fp->ofdm_symbol_size*fp->symbols_per_tti))%10;
proc->frame_rx = (proc->frame_rx+proc->frame_offset)&1023;
proc->frame_tx = proc->frame_rx;
if (proc->subframe_rx > 5) proc->frame_tx=(proc->frame_tx+1)&1023;
// synchronize first reception to frame 0 subframe 0
proc->timestamp_tx = proc->timestamp_rx+(4*fp->ofdm_symbol_size*fp->symbols_per_tti);
// printf("trx_read <- USRP TS %lu (offset %d sf %d, f %d, first_rx %d)\n", proc->timestamp_rx,eNB->ts_offset,proc->subframe_rx,proc->frame_rx,proc->first_rx);
if (proc->first_rx == 0) {
if (proc->subframe_rx != *subframe){
LOG_E(PHY,"rx_rf_freq: Received Timestamp in frequency (%"PRId64") doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)\n",proc->timestamp_rx,proc->subframe_rx,*subframe);
exit_fun("Exiting1");
}
int f2 = (*frame+proc->frame_offset)&1023;
if (proc->frame_rx != f2) {
LOG_E(PHY,"rx_rf_freq: Received Timestamp in frequency (%"PRId64") doesn't correspond to the time we think it is (proc->frame_rx %d frame %d, frame_offset %d, f2 %d)\n",proc->timestamp_rx,proc->frame_rx,*frame,proc->frame_offset,f2);
exit_fun("Exiting2");
}
} else {
proc->first_rx--;
*frame = proc->frame_rx;
*subframe = proc->subframe_rx;
}
//printf("timestamp_rx %lu, frame %d(%d), subframe %d(%d)\n",proc->timestamp_rx,proc->frame_rx,frame,proc->subframe_rx,subframe);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff );
if (rxs_freq != fp->ofdm_symbol_size*fp->symbols_per_tti)
exit_fun( "problem receiving samples in frequency" );
}
void rx_fh_if5(PHY_VARS_eNB *eNB,int *frame, int *subframe) {
LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
......@@ -1346,6 +1483,7 @@ void *eNB_thread_synch(void *arg) {
LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
int32_t sync_pos,sync_pos2;
uint32_t peak_val;
int do_ofdm_mod = PHY_vars_UE_g[0][0]->do_ofdm_mod;
thread_top_init("eNB_thread_synch",0,5000000,10000000,10000000);
......@@ -1366,7 +1504,9 @@ void *eNB_thread_synch(void *arg) {
if (eNB->in_synch == 0) {
// run intial synch like UE
LOG_I(PHY,"Running initial synchronization\n");
if (do_ofdm_mod)
eNB->in_synch=1;
else{
sync_pos = lte_sync_time_eNB(eNB->common_vars.rxdata[0],
fp,
fp->samples_per_tti*5,
......@@ -1407,13 +1547,14 @@ void *eNB_thread_synch(void *arg) {
eNB->in_synch=1;
}
}
}
// release thread
pthread_mutex_lock(&eNB->proc.mutex_synch);
eNB->proc.instance_cnt_synch--;
pthread_mutex_unlock(&eNB->proc.mutex_synch);
} // oai_exit
if (!do_ofdm_mod)
lte_sync_time_free();
return NULL;
......@@ -1579,22 +1720,33 @@ static void* eNB_thread_single( void* param ) {
PHY_VARS_eNB *eNB = PHY_vars_eNB_g[0][proc->CC_id];
LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
eNB->CC_id = proc->CC_id;
int do_ofdm_mod = PHY_vars_UE_g[0][0]->do_ofdm_mod;
void *rxp[2],*rxp2[2];
void *rxp_freq[2],*rxp2_freq[2];
int subframe=0, frame=0;
int32_t dummy_rx_freq[fp->nb_antennas_rx][fp->symbols_per_tti*fp->ofdm_symbol_size] __attribute__((aligned(32)));
int32_t dummy_rx[fp->nb_antennas_rx][fp->samples_per_tti] __attribute__((aligned(32)));
int ic;
int rxs;
int rxs, rxs_freq;
int i;
// initialize the synchronization buffer to the common_vars.rxdata
if (do_ofdm_mod)
{
for (int i=0;i<fp->nb_antennas_rx;i++)
rxp_freq[i] = &eNB->common_vars.rxdataF[0][i][0];
}
else
{
for (int i=0;i<fp->nb_antennas_rx;i++)
rxp[i] = &eNB->common_vars.rxdata[0][i][0];
}
// set default return value
eNB_thread_single_status = 0;
......@@ -1641,6 +1793,18 @@ static void* eNB_thread_single( void* param ) {
while ((eNB->in_synch ==0)&&(!oai_exit)) {
// read in frame
if (do_ofdm_mod){
rxs_freq = eNB->rfdevice.trx_read_func(&eNB->rfdevice,
&(proc->timestamp_rx),
rxp_freq,
fp->symbols_per_tti*fp->ofdm_symbol_size*10,
fp->nb_antennas_rx);
if (rxs_freq != (fp->symbols_per_tti*fp->ofdm_symbol_size*10))
exit_fun("Problem receiving samples in frequency\n");
}
else
{
rxs = eNB->rfdevice.trx_read_func(&eNB->rfdevice,
&(proc->timestamp_rx),
rxp,
......@@ -1649,6 +1813,7 @@ static void* eNB_thread_single( void* param ) {
if (rxs != (fp->samples_per_tti*10))
exit_fun("Problem receiving samples\n");
}
// wakeup synchronization processing thread
wakeup_synch(eNB);
......@@ -1657,7 +1822,20 @@ static void* eNB_thread_single( void* param ) {
while ((ic>=0)&&(!oai_exit)) {
// continuously read in frames, 1ms at a time,
// until we are done with the synchronization procedure
if (do_ofdm_mod){
for (i=0; i<fp->nb_antennas_rx; i++)
rxp2_freq[i] = (void*)&dummy_rx_freq[i][0];
for (i=0;i<10;i++)
rxs_freq = eNB->rfdevice.trx_read_func(&eNB->rfdevice,
&(proc->timestamp_rx),
rxp2_freq,
fp->symbols_per_tti*fp->ofdm_symbol_size,
fp->nb_antennas_rx);
if (rxs_freq != fp->symbols_per_tti*fp->ofdm_symbol_size)
exit_fun( "problem receiving samples in frequency" );
}
else
{
for (i=0; i<fp->nb_antennas_rx; i++)
rxp2[i] = (void*)&dummy_rx[i][0];
for (i=0;i<10;i++)
......@@ -1668,6 +1846,7 @@ static void* eNB_thread_single( void* param ) {
fp->nb_antennas_rx);
if (rxs != fp->samples_per_tti)
exit_fun( "problem receiving samples" );
}
pthread_mutex_lock(&eNB->proc.mutex_synch);
ic = eNB->proc.instance_cnt_synch;
......@@ -1676,6 +1855,17 @@ static void* eNB_thread_single( void* param ) {
} // in_synch==0
// read in rx_offset samples
LOG_I(PHY,"Resynchronizing by %d samples\n",eNB->rx_offset);
if (do_ofdm_mod){
rxs_freq = eNB->rfdevice.trx_read_func(&eNB->rfdevice,
&(proc->timestamp_rx),
rxp_freq,
eNB->rx_offset,
fp->nb_antennas_rx);
if (rxs_freq != eNB->rx_offset)
exit_fun( "problem receiving samples in frequency" );
}
else
{
rxs = eNB->rfdevice.trx_read_func(&eNB->rfdevice,
&(proc->timestamp_rx),
rxp,
......@@ -1683,7 +1873,7 @@ static void* eNB_thread_single( void* param ) {
fp->nb_antennas_rx);
if (rxs != eNB->rx_offset)
exit_fun( "problem receiving samples" );
}
for (i=0;i<4;i++) {
eNB->rfdevice.openair0_cfg->rx_freq[i] = temp_freq1;
eNB->rfdevice.openair0_cfg->tx_freq[i] = temp_freq2;
......@@ -1926,7 +2116,7 @@ int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_c
int i,j;
int CC_id,card,ant;
int do_ofdm_mod = PHY_vars_UE_g[0][0]->do_ofdm_mod;
//uint16_t N_TA_offset = 0;
LTE_DL_FRAME_PARMS *frame_parms;
......@@ -1954,7 +2144,37 @@ int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_c
if (openair0_cfg[CC_id].mmapped_dma == 1) {
// replace RX signal buffers with mmaped HW versions
if (do_ofdm_mod){
for (i=0; i<frame_parms->nb_antennas_rx; i++) {
card = i/4;
ant = i%4;
printf("Mapping eNB CC_id %d, rx_ant %d, on card %d, chain %d\n",CC_id,i,phy_vars_eNB[CC_id]->rf_map.card+card, phy_vars_eNB[CC_id]->rf_map.chain+ant);
free(phy_vars_eNB[CC_id]->common_vars.rxdataF[0][i]);
phy_vars_eNB[CC_id]->common_vars.rxdataF[0][i] = openair0_cfg[phy_vars_eNB[CC_id]->rf_map.card+card].rxbase[phy_vars_eNB[CC_id]->rf_map.chain+ant];
printf("rxdata[%d] @ %p\n",i,phy_vars_eNB[CC_id]->common_vars.rxdataF[0][i]);
for (j=0; j<16; j++) {
printf("rxbuffer %d: %x\n",j,phy_vars_eNB[CC_id]->common_vars.rxdataF[0][i][j]);
phy_vars_eNB[CC_id]->common_vars.rxdataF[0][i][j] = 16-j;
}
}
for (i=0; i<frame_parms->nb_antennas_tx; i++) {
card = i/4;
ant = i%4;
printf("Mapping eNB CC_id %d, tx_ant %d, on card %d, chain %d\n",CC_id,i,phy_vars_eNB[CC_id]->rf_map.card+card, phy_vars_eNB[CC_id]->rf_map.chain+ant);
free(phy_vars_eNB[CC_id]->common_vars.txdataF[0][i]);
phy_vars_eNB[CC_id]->common_vars.txdataF[0][i] = openair0_cfg[phy_vars_eNB[CC_id]->rf_map.card+card].txbase[phy_vars_eNB[CC_id]->rf_map.chain+ant];
printf("txdata[%d] @ %p\n",i,phy_vars_eNB[CC_id]->common_vars.txdataF[0][i]);
for (j=0; j<16; j++) {
printf("txbuffer %d: %x\n",j,phy_vars_eNB[CC_id]->common_vars.txdataF[0][i][j]);
phy_vars_eNB[CC_id]->common_vars.txdataF[0][i][j] = 16-j;
}
}
}
else{
for (i=0; i<frame_parms->nb_antennas_rx; i++) {
card = i/4;
ant = i%4;
......@@ -1984,6 +2204,7 @@ int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_c
}
}
}
}
else { // not memory-mapped DMA
//nothing to do, everything already allocated in lte_init
/*
......@@ -2057,6 +2278,7 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst
int inst;
PHY_VARS_eNB *eNB;
int ret;
int do_ofdm_mod = PHY_vars_UE_g[0][0]->do_ofdm_mod;
for (inst=0;inst<nb_inst;inst++) {
for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
......@@ -2085,7 +2307,7 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst
eNB->proc_uespec_rx = NULL;
eNB->proc_tx = NULL;
eNB->tx_fh = NULL;
eNB->rx_fh = rx_rf;
eNB->rx_fh = (do_ofdm_mod)?rx_rf_freq:rx_rf;
eNB->start_rf = start_rf;
eNB->start_if = start_if;
eNB->fh_asynch = fh_if5_asynch_DL;
......@@ -2115,7 +2337,7 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst
eNB->proc_uespec_rx = NULL;
eNB->proc_tx = NULL;//proc_tx_rru_if4p5;
eNB->tx_fh = NULL;
eNB->rx_fh = rx_rf;
eNB->rx_fh = (do_ofdm_mod)?rx_rf_freq:rx_rf;
eNB->fh_asynch = fh_if4p5_asynch_DL;
eNB->start_rf = start_rf;
eNB->start_if = start_if;
......@@ -2148,7 +2370,7 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst
eNB->proc_uespec_rx = phy_procedures_eNB_uespec_RX;
eNB->proc_tx = proc_tx_full;
eNB->tx_fh = NULL;
eNB->rx_fh = rx_rf;
eNB->rx_fh = (do_ofdm_mod)?rx_rf_freq:rx_rf;
eNB->start_rf = start_rf;
eNB->start_if = NULL;
eNB->fh_asynch = NULL;
......
......@@ -70,10 +70,11 @@ typedef enum {
void init_UE_threads(PHY_VARS_UE *UE);
void *UE_thread(void *arg);
void *UE_thread_freq(void *arg);
void init_UE(int nb_inst);
int32_t **rxdata;
int32_t **txdata;
int32_t **rxdata,**thread0_rxdataF, **thread1_rxdataF;
int32_t **txdata, **txdataF;
#define KHz (1000UL)
#define MHz (1000*KHz)
......@@ -183,7 +184,7 @@ void init_UE(int nb_inst)
PHY_VARS_UE *UE = PHY_vars_UE_g[inst][0];
AssertFatal(0 == pthread_create(&UE->proc.pthread_ue,
&UE->proc.attr_ue,
UE_thread,
(UE->do_ofdm_mod)?UE_thread_freq:UE_thread,
(void*)UE), "");
}
......@@ -475,6 +476,278 @@ static void *UE_thread_synch(void *arg) {
return &UE_thread_synch_retval;
}
/*!
* \brief This is the UE synchronize thread for frequency analysis.
* It performs band scanning and synchonization.
* \param arg is a pointer to a \ref PHY_VARS_UE structure.
* \returns a pointer to an int. The storage is not on the heap and must not be freed.
*/
static void *UE_thread_synch_freq(void *arg) {
static int __thread UE_thread_synch_retval;
int i, hw_slot_offset;
PHY_VARS_UE *UE = (PHY_VARS_UE*) arg;
int current_band = 0;
int current_offset = 0;
sync_mode_t sync_mode = pbch;
int CC_id = UE->CC_id;
int freq_offset=0;
char threadname[128];
int do_ofdm_mod = UE->do_ofdm_mod;
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
if ( threads.iq != -1 )
CPU_SET(threads.iq, &cpuset);
// this thread priority must be lower that the main acquisition thread
sprintf(threadname, "sync UE %d\n", UE->Mod_id);
init_thread(100000, 500000, FIFO_PRIORITY-1, &cpuset, threadname);
UE->is_synchronized = 0;
if (UE->UE_scan == 0) {
int ind;
for ( ind=0;
ind < sizeof(eutra_bands) / sizeof(eutra_bands[0]);
ind++) {
current_band = eutra_bands[ind].band;
LOG_D(PHY, "Scanning band %d, dl_min %"PRIu32", ul_min %"PRIu32"\n", current_band, eutra_bands[ind].dl_min,eutra_bands[ind].ul_min);
if ( eutra_bands[ind].dl_min <= downlink_frequency[0][0] && eutra_bands[ind].dl_max >= downlink_frequency[0][0] ) {
for (i=0; i<4; i++)
uplink_frequency_offset[CC_id][i] = eutra_bands[ind].ul_min - eutra_bands[ind].dl_min;
break;
}
}
AssertFatal( ind < sizeof(eutra_bands) / sizeof(eutra_bands[0]), "Can't find EUTRA band for frequency");
LOG_I( PHY, "[SCHED][UE] Check absolute frequency DL %"PRIu32", UL %"PRIu32" (oai_exit %d, rx_num_channels %d)\n",
downlink_frequency[0][0], downlink_frequency[0][0]+uplink_frequency_offset[0][0],
oai_exit, openair0_cfg[0].rx_num_channels);
for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) {
openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i];
openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] =
downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i];
openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1;
if (uplink_frequency_offset[CC_id][i] != 0) //
openair0_cfg[UE->rf_map.card].duplex_mode = duplex_mode_FDD;
else //FDD
openair0_cfg[UE->rf_map.card].duplex_mode = duplex_mode_TDD;
}
sync_mode = pbch;
} else {
current_band=0;
for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) {
downlink_frequency[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[CC_id].dl_min;
uplink_frequency_offset[UE->rf_map.card][UE->rf_map.chain+i] =
bands_to_scan.band_info[CC_id].ul_min-bands_to_scan.band_info[CC_id].dl_min;
openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i];
openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] =
downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i];
openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;
}
}
while (oai_exit==0) {
AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), "");
while (UE->proc.instance_cnt_synch < 0)
// the thread waits here most of the time
pthread_cond_wait( &UE->proc.cond_synch, &UE->proc.mutex_synch );
AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), "");
switch (sync_mode) {
case pss:
//printf("pss case in UE_thread_synch\n");
LOG_I(PHY,"[SCHED][UE] Scanning band %d (%d), freq %u\n",bands_to_scan.band_info[current_band].band, current_band,bands_to_scan.band_info[current_band].dl_min+current_offset);
//lte_sync_freqtime(UE,current_band,bands_to_scan.band_info[current_band].dl_min+current_offset);
current_offset += 20000000; // increase by 20 MHz
if (current_offset > bands_to_scan.band_info[current_band].dl_max-bands_to_scan.band_info[current_band].dl_min) {
current_band++;
current_offset=0;
}
if (current_band==bands_to_scan.nbands) {
current_band=0;
oai_exit=1;
}
for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) {
downlink_frequency[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[current_band].dl_min+current_offset;
uplink_frequency_offset[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[current_band].ul_min-bands_to_scan.band_info[0].dl_min + current_offset;
openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i];
openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i];
openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;
if (UE->UE_scan_carrier) {
openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1;
}
}
break;
case pbch:
LOG_I(PHY,"[UE thread Synch] Running Initial frequency Synch (mode %d), initial_synch is %d\n",UE->mode,initial_sync_freq( UE, UE->mode ));
//Pushed N_RB_DL, PHICH_CONFIG, FRAME_NUMBER
if (initial_sync_freq( UE, UE->mode ) == 0) {
hw_slot_offset = (UE->rx_offset<<1) / (UE->frame_parms.ofdm_symbol_size*UE->frame_parms.symbols_per_tti);
LOG_I( HW, "Got synch: hw_slot_offset %d, carrier off %d Hz, rxgain %d (DL %u, UL %u), UE_scan_carrier %d\n",
hw_slot_offset,
freq_offset,
UE->rx_total_gain_dB,
downlink_frequency[0][0]+freq_offset,
downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset,
UE->UE_scan_carrier );
printf("UE_scan_carrier in case pbch %d\n",UE->UE_scan_carrier);
// rerun with new cell parameters and frequency-offset
for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) {
openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET;
if (UE->UE_scan_carrier == 1) {
if (freq_offset >= 0)
openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] += abs(UE->common_vars.freq_offset);
else
openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] -= abs(UE->common_vars.freq_offset);
openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] =
openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i]+uplink_frequency_offset[CC_id][i];
downlink_frequency[CC_id][i] = openair0_cfg[CC_id].rx_freq[i];
freq_offset=0;
}
}
// reconfigure for potentially different bandwidth
switch(UE->frame_parms.N_RB_DL) {
case 6:
openair0_cfg[UE->rf_map.card].sample_rate =1.92e6;
openair0_cfg[UE->rf_map.card].rx_bw =.96e6;
openair0_cfg[UE->rf_map.card].tx_bw =.96e6;
// openair0_cfg[0].rx_gain[0] -= 12;
break;
case 25:
openair0_cfg[UE->rf_map.card].sample_rate =7.68e6;
openair0_cfg[UE->rf_map.card].rx_bw =2.5e6;
openair0_cfg[UE->rf_map.card].tx_bw =2.5e6;
// openair0_cfg[0].rx_gain[0] -= 6;
break;
case 50:
openair0_cfg[UE->rf_map.card].sample_rate =15.36e6;
openair0_cfg[UE->rf_map.card].rx_bw =5.0e6;
openair0_cfg[UE->rf_map.card].tx_bw =5.0e6;
// openair0_cfg[0].rx_gain[0] -= 3;
break;
case 100:
openair0_cfg[UE->rf_map.card].sample_rate=30.72e6;
openair0_cfg[UE->rf_map.card].rx_bw=10.0e6;
openair0_cfg[UE->rf_map.card].tx_bw=10.0e6;
// openair0_cfg[0].rx_gain[0] -= 0;
break;
}
UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0);
//UE->rfdevice.trx_set_gains_func(&openair0,&openair0_cfg[0]);
//UE->rfdevice.trx_stop_func(&UE->rfdevice);
sleep(1);
init_frame_parms(&UE->frame_parms,1);
//UE->proc.proc_rxtx[0].frame_rx=PHY_vars_eNB_g[0][0]->proc.proc_rxtx[0].frame_tx;
//UE->proc.proc_rxtx[1].frame_rx=PHY_vars_eNB_g[0][0]->proc.proc_rxtx[0].frame_tx;
//UE->frame_parms.phich_config_common.phich_duration=PHY_vars_eNB_g[0][0]->frame_parms.phich_config_common.phich_duration;
//UE->frame_parms.phich_config_common.phich_resource=PHY_vars_eNB_g[0][0]->frame_parms.phich_config_common.phich_resource;
/*if (UE->rfdevice.trx_start_func(&UE->rfdevice) != 0 ) {
LOG_E(HW,"Could not start the device\n");
oai_exit=1;
}*/
if (UE->UE_scan_carrier == 1) {
UE->UE_scan_carrier = 0;
} else {
AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), "");
UE->is_synchronized = 1;
AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), "");
/*if( UE->mode == rx_dump_frame ) {
FILE *fd;
if ((UE->proc.proc_rxtx[0].frame_rx&1) == 0) { // this guarantees SIB1 is present
if ((fd = fopen("rxsig_frame0.dat","w")) != NULL) {
fwrite((void*)&UE->common_vars.rxdata[0][0],
sizeof(int32_t),
10*UE->frame_parms.samples_per_tti,
fd);
LOG_I(PHY,"Dummping Frame ... bye bye \n");
fclose(fd);
exit(0);
} else {
LOG_E(PHY,"Cannot open file for writing\n");
exit(0);
}
} else {
AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), "");
UE->is_synchronized = 0;
AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), "");
}
}*/
}
/*} else {
// initial sync failed
// calculate new offset and try again
if (UE->UE_scan_carrier == 1) {
if (freq_offset >= 0)
freq_offset += 100;
freq_offset *= -1;
if (abs(freq_offset) > 7500) {
LOG_I( PHY, "[initial_sync] No cell synchronization found, abandoning\n" );
FILE *fd;
if ((fd = fopen("rxsig_frame0.dat","w"))!=NULL) {
fwrite((void*)&UE->common_vars.rxdata[0][0],
sizeof(int32_t),
10*UE->frame_parms.samples_per_tti,
fd);
LOG_I(PHY,"Dummping Frame ... bye bye \n");
fclose(fd);
exit(0);
}
mac_xface->macphy_exit("No cell synchronization found, abandoning");
return &UE_thread_synch_retval; // not reached
}
}
LOG_I( PHY, "[initial_sync] trying carrier off %d Hz, rxgain %d (DL %u, UL %u)\n",
freq_offset,
UE->rx_total_gain_dB,
downlink_frequency[0][0]+freq_offset,
downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset );
for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) {
openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+freq_offset;
openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]+freq_offset;
openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET;
if (UE->UE_scan_carrier==1)
openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1;
}
UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0);*/
}// initial_sync=0
break;
case si:
default:
break;
}
AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), "");
// indicate readiness
UE->proc.instance_cnt_synch--;
AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), "");
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_THREAD_SYNCH, 0 );
} // while !oai_exit
return &UE_thread_synch_retval;
}
/*!
* \brief This is the UE thread for RX subframe n and TX subframe n+4.
......@@ -754,11 +1027,18 @@ void *UE_thread(void *arg) {
} else {
sub_frame++;
sub_frame%=10;
UE_rxtx_proc_t *proc = &UE->proc.proc_rxtx[thread_idx];
// update thread index for received subframe
UE->current_thread_id[sub_frame] = thread_idx;
LOG_D(PHY,"Process Subframe %d thread Idx %d \n", sub_frame, UE->current_thread_id[sub_frame]);
LOG_D(PHY,"Process Subframe %d thread Idx %d , frame %d \n", sub_frame, UE->current_thread_id[sub_frame],proc->frame_rx);
if (sub_frame==6 && ((proc->frame_rx&0x1)==0))
{
write_output("lteue_rxsigF_frame0.m","lteue_rxsF0", UE->common_vars.common_vars_rx_data_per_thread[0].rxdataF[0],10*UE->frame_parms.ofdm_symbol_size*UE->frame_parms.symbols_per_tti,1,16);
write_output("lteue_rxsigF_frame1.m","lteue_rxsF1", UE->common_vars.common_vars_rx_data_per_thread[1].rxdataF[0],10*UE->frame_parms.ofdm_symbol_size*UE->frame_parms.symbols_per_tti,1,16);
exit(-1);
}
thread_idx++;
if(thread_idx>=RX_NB_TH)
......@@ -850,6 +1130,7 @@ void *UE_thread(void *arg) {
proc->instance_cnt_rxtx++;
LOG_D( PHY, "[SCHED][UE %d] UE RX instance_cnt_rxtx %d subframe %d !!\n", UE->Mod_id, proc->instance_cnt_rxtx,proc->subframe_rx);
if (proc->instance_cnt_rxtx == 0) {
if (pthread_cond_signal(&proc->cond_rxtx) != 0) {
LOG_E( PHY, "[SCHED][UE %d] ERROR pthread_cond_signal for UE RX thread\n", UE->Mod_id);
......@@ -867,7 +1148,6 @@ void *UE_thread(void *arg) {
initStaticTime(lastTime);
updateTimes(lastTime, &t1, 20000, "Delay between two IQ acquisitions (case 1)");
pickStaticTime(lastTime);
} else {
printf("Processing subframe %d",proc->subframe_rx);
getchar();
......@@ -878,7 +1158,282 @@ void *UE_thread(void *arg) {
} // while !oai_exit
return NULL;
}
/*!
* \brief This is the main UE thread for frequency analysis.
* This thread controls the other three UE threads:
* - UE_thread_rxn_txnp4 (even subframes)
* - UE_thread_rxn_txnp4 (odd subframes)
* - UE_thread_synch_freq
* \param arg unused
* \returns a pointer to an int. The storage is not on the heap and must not be freed.
*/
void *UE_thread_freq(void *arg) {
PHY_VARS_UE *UE = (PHY_VARS_UE *) arg;
// int tx_enabled = 0;
int dummy_rx[UE->frame_parms.nb_antennas_rx][UE->frame_parms.symbols_per_tti*UE->frame_parms.ofdm_symbol_size] __attribute__((aligned(32)));
openair0_timestamp timestamp,timestamp1;
void* rxp_freq[NB_ANTENNAS_RX];
void* txp_freq[NB_ANTENNAS_TX];
int start_rx_stream = 0;
int i;
char threadname[128];
int th_id;
static uint8_t thread_idx = 0;
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
if ( threads.iq != -1 )
CPU_SET(threads.iq, &cpuset);
init_thread(100000, 500000, FIFO_PRIORITY, &cpuset,
"UHD Threads");
if (oaisim_flag == 0)
AssertFatal(0== openair0_device_load(&(UE->rfdevice), &openair0_cfg[0]), "");
UE->rfdevice.host_type = BBU_HOST;
sprintf(threadname, "Main UE %d", UE->Mod_id);
pthread_setname_np(pthread_self(), threadname);
init_UE_threads(UE);
#ifdef NAS_UE
MessageDef *message_p;
message_p = itti_alloc_new_message(TASK_NAS_UE, INITIALIZE_MESSAGE);
itti_send_msg_to_task (TASK_NAS_UE, UE->Mod_id + NB_eNB_INST, message_p);
#endif
int sub_frame=-1;
//int cumulated_shift=0;
AssertFatal(UE->rfdevice.trx_start_func(&UE->rfdevice) == 0, "Could not start the device\n");
while (!oai_exit) {
AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), "");
int instance_cnt_synch = UE->proc.instance_cnt_synch;
int is_synchronized = UE->is_synchronized;
//printf("[ue_thread] UE is synchronized: %d, instance_cnt_synch: %d\n",is_synchronized,instance_cnt_synch);
AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), "");
if (is_synchronized == 0) {
if (instance_cnt_synch < 0) { // we can invoke the synch
// grab 10 ms of signal and wakeup synch thread
for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++)
{
rxp_freq[i] = (void*)&UE->common_vars.common_vars_rx_data_per_thread[0].rxdataF[i][0];
}
if (UE->mode != loop_through_memory)
{
printf("[ue_thread] UE->mode != loop_through_memory: %d\n",UE->mode != loop_through_memory);
AssertFatal( UE->frame_parms.ofdm_symbol_size*UE->frame_parms.symbols_per_tti*10 ==
UE->rfdevice.trx_read_func(&UE->rfdevice,
&timestamp,
rxp_freq,
UE->frame_parms.ofdm_symbol_size*UE->frame_parms.symbols_per_tti*10,
UE->frame_parms.nb_antennas_rx), "");
}
AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), "");
instance_cnt_synch = ++UE->proc.instance_cnt_synch;
if (instance_cnt_synch == 0) {
AssertFatal( 0 == pthread_cond_signal(&UE->proc.cond_synch), "");
} else {
LOG_E( PHY, "[SCHED][UE] UE sync thread busy!!\n" );
exit_fun("nothing to add");
}
AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), "");
} else {
#if OAISIM
(void)dummy_rx; /* avoid gcc warnings */
usleep(500);
#else
printf("[ue_thread] is_synchronized == 0 and instance_cnt_synch == %d\n",instance_cnt_synch);
// grab 10 ms of signal into dummy buffer
if (UE->mode != loop_through_memory) {
for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++)
{
rxp_freq[i] = (void*)&dummy_rx[i][0];
}
for (int sf=0; sf<10; sf++)
{
UE->rfdevice.trx_read_func(&UE->rfdevice,
&timestamp,
rxp_freq,
UE->frame_parms.ofdm_symbol_size*UE->frame_parms.symbols_per_tti,
UE->frame_parms.nb_antennas_rx);
}
}
#endif
}
} // UE->is_synchronized==0
else {
if (start_rx_stream==0) {
start_rx_stream=1;
//printf("[ue_thread] UE is synch and start_rx_stream change from 0 to %d, UE->rx_offset %d \n",start_rx_stream,UE->rx_offset);
if (UE->mode != loop_through_memory) {
/*if (UE->no_timing_correction==0) {//no_timing_correction is loaded to 1 in oaisim_functions.c
LOG_I(PHY,"Resynchronizing RX by %d samples (mode = %d)\n",UE->rx_offset,UE->mode);
AssertFatal(UE->rx_offset ==
UE->rfdevice.trx_read_func(&UE->rfdevice,
&timestamp,
(void**)UE->common_vars.common_vars_rx_data_per_thread[0].rxdataF,
UE->rx_offset,
UE->frame_parms.nb_antennas_rx),"");
AssertFatal(UE->rx_offset ==
UE->rfdevice.trx_read_func(&UE->rfdevice,
&timestamp,
(void**)UE->common_vars.common_vars_rx_data_per_thread[1].rxdataF,
UE->rx_offset,
UE->frame_parms.nb_antennas_rx),"");
}*/
UE->rx_offset=0;
UE->time_sync_cell=0;
//UE->proc.proc_rxtx[0].frame_rx++;
//UE->proc.proc_rxtx[1].frame_rx++;
for (th_id=0; th_id < RX_NB_TH; th_id++) {
UE->proc.proc_rxtx[th_id].frame_rx++;
}
// read in first symbol
AssertFatal (UE->frame_parms.ofdm_symbol_size ==
UE->rfdevice.trx_read_func(&UE->rfdevice,
&timestamp,
(void**)UE->common_vars.common_vars_rx_data_per_thread[0].rxdataF,
UE->frame_parms.ofdm_symbol_size,
UE->frame_parms.nb_antennas_rx),"");
slot_fep_freq(UE,0, 0, 0, 0, 0);
printf("slot_fep_freq in lte_ue (if)\n");
} //UE->mode != loop_through_memory
else
{
rt_sleep_ns(1000*1000);
printf("slot_fep_freq in lte_ue (else)\n");
}
}
else {
//printf("[ue_thread] is synch %d, start_rx_stream= %d, instance_cnt_synch %d, openair0_cfg[0].tx_sample_advance %d \n",is_synchronized,start_rx_stream,instance_cnt_synch,openair0_cfg[0].tx_sample_advance);
sub_frame++;
sub_frame%=10;
UE_rxtx_proc_t *proc = &UE->proc.proc_rxtx[thread_idx];
// update thread index for received subframe
UE->current_thread_id[sub_frame] = thread_idx;
LOG_D(PHY,"Process Subframe %d thread Idx %d , frame %d \n", sub_frame, UE->current_thread_id[sub_frame],proc->frame_rx);
if (sub_frame==5 && ((proc->frame_rx&0x1)==0))
{
write_output("lteue_rxsigF_frame0.m","lteue_rxsF0", UE->common_vars.common_vars_rx_data_per_thread[0].rxdataF[0],10*UE->frame_parms.ofdm_symbol_size*UE->frame_parms.symbols_per_tti,1,16);
write_output("lteue_rxsigF_frame1.m","lteue_rxsF1", UE->common_vars.common_vars_rx_data_per_thread[1].rxdataF[0],10*UE->frame_parms.ofdm_symbol_size*UE->frame_parms.symbols_per_tti,1,16);
//exit(-1);
}
thread_idx++;
if(thread_idx>=RX_NB_TH)
thread_idx = 0;
if (UE->mode != loop_through_memory) {
for (i=0; i<UE->frame_parms.nb_antennas_rx; i++){
rxp_freq[i] = (void*)&UE->common_vars.common_vars_rx_data_per_thread[sub_frame&0x1].rxdataF[i][UE->frame_parms.ofdm_symbol_size+sub_frame*UE->frame_parms.ofdm_symbol_size*UE->frame_parms.symbols_per_tti];//14*1024->50RB
}
for (i=0; i<UE->frame_parms.nb_antennas_tx; i++)
txp_freq[i] = (void*)&UE->common_vars.txdataF[i][
((sub_frame+2)%10)*UE->frame_parms.ofdm_symbol_size*UE->frame_parms.symbols_per_tti];
int readBlockSize, writeBlockSize;
if (sub_frame<9) {
readBlockSize= UE->frame_parms.ofdm_symbol_size*UE->frame_parms.symbols_per_tti;
writeBlockSize=UE->frame_parms.ofdm_symbol_size*UE->frame_parms.symbols_per_tti;
} else {
/* set TO compensation to zero
UE->rx_offset_diff = 0;
// compute TO compensation that should be applied for this frame
if ( UE->rx_offset < 5*UE->frame_parms.samples_per_tti &&
UE->rx_offset > 0 )
UE->rx_offset_diff = -1 ;
if ( UE->rx_offset > 5*UE->frame_parms.samples_per_tti &&
UE->rx_offset < 10*UE->frame_parms.samples_per_tti )
UE->rx_offset_diff = 1;
LOG_D(PHY,"AbsSubframe %d.%d SET rx_off_diff to %d rx_offset %d \n",proc->frame_rx,sub_frame,UE->rx_offset_diff,UE->rx_offset);*/
readBlockSize=UE->frame_parms.ofdm_symbol_size*UE->frame_parms.symbols_per_tti -
UE->frame_parms.ofdm_symbol_size;
writeBlockSize=UE->frame_parms.ofdm_symbol_size*UE->frame_parms.symbols_per_tti;
}
LOG_D(PHY,"AbsSubframe %d.%d SET rx_off_diff to %d rx_offset %d \n",proc->frame_rx,sub_frame,UE->rx_offset_diff,UE->rx_offset);
AssertFatal(readBlockSize == UE->rfdevice.trx_read_func(&UE->rfdevice,
&timestamp,
rxp_freq,
readBlockSize,
UE->frame_parms.nb_antennas_rx),"");
AssertFatal( writeBlockSize ==
UE->rfdevice.trx_write_func(&UE->rfdevice,
timestamp+
(2*UE->frame_parms.ofdm_symbol_size*UE->frame_parms.symbols_per_tti) -
UE->frame_parms.ofdm_symbol_size,
txp_freq,
writeBlockSize,
UE->frame_parms.nb_antennas_tx,
1),"");
if( sub_frame==9) {
// read in first symbol of next frame and adjust for timing drift
if ( writeBlockSize-readBlockSize > 0 )
AssertFatal(writeBlockSize-readBlockSize ==
UE->rfdevice.trx_read_func(&UE->rfdevice,
&timestamp1,
(void**)UE->common_vars.common_vars_rx_data_per_thread[sub_frame&0x1].rxdataF,
writeBlockSize-readBlockSize,
UE->frame_parms.nb_antennas_rx),"");
if ( writeBlockSize-readBlockSize <0 )
LOG_E(PHY,"can't compensate: diff =%d\n", writeBlockSize-readBlockSize);
}
//pickTime(gotIQs);
// operate on thread sf mod 2
AssertFatal(pthread_mutex_lock(&proc->mutex_rxtx) ==0,"");
if(sub_frame == 0) {
//UE->proc.proc_rxtx[0].frame_rx++;
//UE->proc.proc_rxtx[1].frame_rx++;
for (th_id=0; th_id < RX_NB_TH; th_id++) {
UE->proc.proc_rxtx[th_id].frame_rx++;
}
}
//UE->proc.proc_rxtx[0].gotIQs=readTime(gotIQs);
//UE->proc.proc_rxtx[1].gotIQs=readTime(gotIQs);
proc->subframe_rx=sub_frame;
proc->subframe_tx=(sub_frame+4)%10;
proc->frame_tx = proc->frame_rx + (proc->subframe_rx>5?1:0);
proc->timestamp_tx = timestamp+
(4*UE->frame_parms.ofdm_symbol_size*UE->frame_parms.symbols_per_tti)-
UE->frame_parms.ofdm_symbol_size;
proc->instance_cnt_rxtx++;
LOG_D( PHY, "[SCHED][UE %d] UE RX instance_cnt_rxtx %d subframe %d !!\n", UE->Mod_id, proc->instance_cnt_rxtx,proc->subframe_rx);
if (proc->instance_cnt_rxtx == 0) {
if (pthread_cond_signal(&proc->cond_rxtx) != 0) {
LOG_E( PHY, "[SCHED][UE %d] ERROR pthread_cond_signal for UE RX thread\n", UE->Mod_id);
exit_fun("nothing to add");
}
} else {
LOG_E( PHY, "[SCHED][UE %d] UE RX thread busy (IC %d)!!\n", UE->Mod_id, proc->instance_cnt_rxtx);
if (proc->instance_cnt_rxtx > 2)
exit_fun("instance_cnt_rxtx > 2");
}
AssertFatal (pthread_cond_signal(&proc->cond_rxtx) ==0 ,"");
AssertFatal(pthread_mutex_unlock(&proc->mutex_rxtx) ==0,"");
//initRefTimes(t1);
//initStaticTime(lastTime);
//updateTimes(lastTime, &t1, 20000, "Delay between two IQ acquisitions (case 1)");
//pickStaticTime(lastTime);
} else {
printf("Processing subframe %d",proc->subframe_rx);
getchar();
}
} // start_rx_stream==1
} // UE->is_synchronized==1
} // while !oai_exit
return NULL;
}
/*!
* \brief Initialize the UE theads.
* Creates the UE threads:
......@@ -926,7 +1481,7 @@ void init_UE_threads(PHY_VARS_UE *UE) {
#endif
}
pthread_create(&UE->proc.pthread_synch,NULL,UE_thread_synch,(void*)UE);
pthread_create(&UE->proc.pthread_synch,NULL,(UE->do_ofdm_mod)?UE_thread_synch_freq:UE_thread_synch,(void*)UE);
}
......@@ -965,6 +1520,7 @@ int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg)
int i, CC_id;
LTE_DL_FRAME_PARMS *frame_parms;
openair0_rf_map *rf_map;
int do_ofdm_mod = phy_vars_ue[0]->do_ofdm_mod;
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
rf_map = &phy_vars_ue[CC_id]->rf_map;
......@@ -973,9 +1529,36 @@ int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg)
frame_parms = &(phy_vars_ue[CC_id]->frame_parms);
// replace RX signal buffers with mmaped HW versions
if (do_ofdm_mod){//if do_ofdm_mod, frequency analysis
thread0_rxdataF = (int32_t**)malloc16( frame_parms->nb_antennas_rx*sizeof(int32_t*) );
thread1_rxdataF = (int32_t**)malloc16( frame_parms->nb_antennas_rx*sizeof(int32_t*) );
txdataF = (int32_t**)malloc16( frame_parms->nb_antennas_tx*sizeof(int32_t*) );
}
else{//time analysis
rxdata = (int32_t**)malloc16( frame_parms->nb_antennas_rx*sizeof(int32_t*) );
txdata = (int32_t**)malloc16( frame_parms->nb_antennas_tx*sizeof(int32_t*) );
}
if (do_ofdm_mod){//if do_ofdm_mod, frequency analysis
for (i=0; i<frame_parms->nb_antennas_rx; i++) {
LOG_I(PHY, "Mapping UE CC_id %d, rx_ant %d, freq %u on card %d, chain %d\n",
CC_id, i, downlink_frequency[CC_id][i], rf_map->card, rf_map->chain+i );
free( phy_vars_ue[CC_id]->common_vars.common_vars_rx_data_per_thread[0].rxdataF[i] );
free( phy_vars_ue[CC_id]->common_vars.common_vars_rx_data_per_thread[1].rxdataF[i] );
thread0_rxdataF[i] = (int32_t*)malloc16_clear( frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti*sizeof(int32_t) );
thread1_rxdataF[i] = (int32_t*)malloc16_clear( frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti*sizeof(int32_t) );
phy_vars_ue[CC_id]->common_vars.common_vars_rx_data_per_thread[0].rxdataF[i] = thread0_rxdataF[i]; // what about the "-N_TA_offset" ? // N_TA offset for TDD
phy_vars_ue[CC_id]->common_vars.common_vars_rx_data_per_thread[1].rxdataF[i] = thread1_rxdataF[i]; // what about the "-N_TA_offset" ? // N_TA offset for TDD
}
for (i=0; i<frame_parms->nb_antennas_tx; i++) {
LOG_I(PHY, "Mapping UE CC_id %d, tx_ant %d, freq %u on card %d, chain %d\n",
CC_id, i, downlink_frequency[CC_id][i], rf_map->card, rf_map->chain+i );
free( phy_vars_ue[CC_id]->common_vars.txdataF[i] );
txdataF[i] = (int32_t*)malloc16_clear( 10*frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti*sizeof(int32_t) );
phy_vars_ue[CC_id]->common_vars.txdataF[i] = txdataF[i];
}
}
else{//else, time analysis
for (i=0; i<frame_parms->nb_antennas_rx; i++) {
LOG_I(PHY, "Mapping UE CC_id %d, rx_ant %d, freq %u on card %d, chain %d\n",
CC_id, i, downlink_frequency[CC_id][i], rf_map->card, rf_map->chain+i );
......@@ -997,6 +1580,7 @@ int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg)
// be careful when releasing memory!
// because no "release_ue_buffers"-function is available, at least rxdata and txdata memory will leak (only some bytes)
}
}
return 0;
}
......@@ -60,7 +60,7 @@
#include "oaisim.h"
#define RF
#define DEBUG_SIM
//#define DEBUG_SIM
int number_rb_ul;
int first_rbUL ;
......@@ -72,6 +72,14 @@ double r_re_DL[NUMBER_OF_UE_MAX][2][30720];
double r_im_DL[NUMBER_OF_UE_MAX][2][30720];
double r_re_UL[NUMBER_OF_eNB_MAX][2][30720];
double r_im_UL[NUMBER_OF_eNB_MAX][2][30720];
double r_re_DL_f[NUMBER_OF_UE_MAX][2][2048*14];
double r_im_DL_f[NUMBER_OF_UE_MAX][2][2048*14];
double r_re_UL_f[NUMBER_OF_eNB_MAX][2][2048*14];
double r_im_UL_f[NUMBER_OF_eNB_MAX][2][2048*14];
double r_re_UL_f_prach[NUMBER_OF_eNB_MAX][2][2048*14*12];
double r_im_UL_f_prach[NUMBER_OF_eNB_MAX][2][2048*14*12];
int eNB_output_mask[NUMBER_OF_UE_MAX];
int UE_output_mask[NUMBER_OF_eNB_MAX];
pthread_mutex_t eNB_output_mutex[NUMBER_OF_UE_MAX];
......@@ -364,6 +372,318 @@ void do_DL_sig(channel_desc_t *eNB2UE[NUMBER_OF_eNB_MAX][NUMBER_OF_UE_MAX][MAX_N
}
}
void do_DL_sig_freq(channel_desc_t *eNB2UE[NUMBER_OF_eNB_MAX][NUMBER_OF_UE_MAX][MAX_NUM_CCs],
node_desc_t *enb_data[NUMBER_OF_eNB_MAX],
node_desc_t *ue_data[NUMBER_OF_UE_MAX],
uint16_t subframe,uint8_t abstraction_flag,LTE_DL_FRAME_PARMS *frame_parms,
uint8_t UE_id,
int CC_id)
{
int32_t att_eNB_id=-1;
int32_t **txdata,**txdataF,**rxdata,**rxdataF;
uint8_t eNB_id=0;
double tx_pwr;
double rx_pwr;
int32_t rx_pwr0,rx_pwr1,rx_pwr2, rx_pwr3;
uint32_t i,aa;
uint32_t sf_offset;
double min_path_loss=-200;
uint8_t hold_channel=0;
uint8_t nb_antennas_rx = eNB2UE[0][0][CC_id]->nb_rx; // number of rx antennas at UE
uint8_t nb_antennas_tx = eNB2UE[0][0][CC_id]->nb_tx; // number of tx antennas at eNB
double s_re0_f[2048*14];//ofdm_symbol_size*symbols_per_tti;
double s_re1_f[2048*14];//ofdm_symbol_size*symbols_per_tti;
double *s_re_f[2];
double s_im0_f[2048*14];//ofdm_symbol_size*symbols_per_tti;
double s_im1_f[2048*14];//ofdm_symbol_size*symbols_per_tti;
double *s_im_f[2];
double r_re00_f[2048*14];//ofdm_symbol_size*symbols_per_tti;
double r_re01_f[2048*14];//ofdm_symbol_size*symbols_per_tti;
double *r_re0_f[2];
double r_im00_f[2048*14];//ofdm_symbol_size*symbols_per_tti;
double r_im01_f[2048*14];//ofdm_symbol_size*symbols_per_tti;
double *r_im0_f[2];
int x,y;
s_re_f[0] = s_re0_f;
s_im_f[0] = s_im0_f;
s_re_f[1] = s_re1_f;
s_im_f[1] = s_im1_f;
r_re0_f[0] = r_re00_f;
r_im0_f[0] = r_im00_f;
r_re0_f[1] = r_re01_f;
r_im0_f[1] = r_im01_f;
FILE *file1;
file1 = fopen("sre_sim.txt","w");
int j;
if (subframe==0)
hold_channel = 0;
else
hold_channel = 1;
if (abstraction_flag != 0) {
/*//for (UE_id=0;UE_id<NB_UE_INST;UE_id++) {
if (!hold_channel) {
// calculate the random channel from each eNB
for (eNB_id=0; eNB_id<NB_eNB_INST; eNB_id++) {
random_channel(eNB2UE[eNB_id][UE_id][CC_id],abstraction_flag);*/
/*
for (i=0;i<eNB2UE[eNB_id][UE_id]->nb_taps;i++)
printf("eNB2UE[%d][%d]->a[0][%d] = (%f,%f)\n",eNB_id,UE_id,i,eNB2UE[eNB_id][UE_id]->a[0][i].x,eNB2UE[eNB_id][UE_id]->a[0][i].y);
*/
/*freq_channel(eNB2UE[eNB_id][UE_id][CC_id], frame_parms->N_RB_DL,frame_parms->N_RB_DL*12+1);
}
// find out which eNB the UE is attached to
for (eNB_id=0; eNB_id<NB_eNB_INST; eNB_id++) {
if (find_ue(PHY_vars_UE_g[UE_id][CC_id]->pdcch_vars[0][0]->crnti,PHY_vars_eNB_g[eNB_id][CC_id])>=0) {
// UE with UE_id is connected to eNb with eNB_id
att_eNB_id=eNB_id;
LOG_D(OCM,"A: UE attached to eNB (UE%d->eNB%d)\n",UE_id,eNB_id);
}
}
// if UE is not attached yet, find assume its the eNB with the smallest pathloss
if (att_eNB_id<0) {
for (eNB_id=0; eNB_id<NB_eNB_INST; eNB_id++) {
if (min_path_loss<eNB2UE[eNB_id][UE_id][CC_id]->path_loss_dB) {
min_path_loss = eNB2UE[eNB_id][UE_id][CC_id]->path_loss_dB;
att_eNB_id=eNB_id;
LOG_D(OCM,"B: UE attached to eNB (UE%d->eNB%d)\n",UE_id,eNB_id);
}
}
}
if (att_eNB_id<0) {
LOG_E(OCM,"Cannot find eNB for UE %d, return\n",UE_id);
return; //exit(-1);
}
#ifdef DEBUG_SIM
rx_pwr = signal_energy_fp2(eNB2UE[att_eNB_id][UE_id][CC_id]->ch[0],
eNB2UE[att_eNB_id][UE_id][CC_id]->channel_length)*eNB2UE[att_eNB_id][UE_id][CC_id]->channel_length;
/*LOG_D(OCM,"Channel (CCid %d) eNB %d => UE %d : tx_power %d dBm, path_loss %f dB\n",
CC_id,att_eNB_id,UE_id,
frame_parms->pdsch_config_common.referenceSignalPower,
eNB2UE[att_eNB_id][UE_id][CC_id]->path_loss_dB);*/
//#endif
//dlsch_abstraction(PHY_vars_UE_g[UE_id]->sinr_dB, rb_alloc, 8);
// fill in perfect channel estimates
/*channel_desc_t *desc1 = eNB2UE[att_eNB_id][UE_id][CC_id];
int32_t **dl_channel_est = PHY_vars_UE_g[UE_id][CC_id]->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[0];
// double scale = pow(10.0,(enb_data[att_eNB_id]->tx_power_dBm + eNB2UE[att_eNB_id][UE_id]->path_loss_dB + (double) PHY_vars_UE_g[UE_id]->rx_total_gain_dB)/20.0);
double scale = pow(10.0,(frame_parms->pdsch_config_common.referenceSignalPower+eNB2UE[att_eNB_id][UE_id][CC_id]->path_loss_dB + (double) PHY_vars_UE_g[UE_id][CC_id]->rx_total_gain_dB)/20.0);
LOG_D(OCM,"scale =%lf (%d dB)\n",scale,(int) (20*log10(scale)));
// freq_channel(desc1,frame_parms->N_RB_DL,nb_samples);
//write_output_xrange("channel.m","ch",desc1->ch[0],desc1->channel_length,1,8);
//write_output_xrange("channelF.m","chF",desc1->chF[0],nb_samples,1,8);
int count,count1,a_rx,a_tx;
for(a_tx=0; a_tx<nb_antennas_tx; a_tx++) {
for (a_rx=0; a_rx<nb_antennas_rx; a_rx++) {
//for (count=0;count<frame_parms->symbols_per_tti/2;count++)
for (count=0; count<1; count++) {
for (count1=0; count1<frame_parms->N_RB_DL*12; count1++) {
((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count1+(count*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(int16_t)(desc1->chF[a_rx+(a_tx*nb_antennas_rx)][count1].x*scale);
((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count1+1+(count*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(int16_t)(desc1->chF[a_rx+(a_tx*nb_antennas_rx)][count1].y*scale) ;
}
}
}
}
// calculate the SNR for the attached eNB (this assumes eNB always uses PMI stored in eNB_UE_stats; to be improved)
init_snr(eNB2UE[att_eNB_id][UE_id][CC_id], enb_data[att_eNB_id], ue_data[UE_id], PHY_vars_UE_g[UE_id][CC_id]->sinr_dB, &PHY_vars_UE_g[UE_id][CC_id]->N0,
PHY_vars_UE_g[UE_id][CC_id]->transmission_mode[att_eNB_id], PHY_vars_eNB_g[att_eNB_id][CC_id]->UE_stats[UE_id].DL_pmi_single,
PHY_vars_eNB_g[att_eNB_id][CC_id]->mu_mimo_mode[UE_id].dl_pow_off,PHY_vars_eNB_g[att_eNB_id][CC_id]->frame_parms.N_RB_DL);
// calculate sinr here
for (eNB_id = 0; eNB_id < NB_eNB_INST; eNB_id++) {
if (att_eNB_id != eNB_id) {
calculate_sinr(eNB2UE[eNB_id][UE_id][CC_id], enb_data[eNB_id], ue_data[UE_id], PHY_vars_UE_g[UE_id][CC_id]->sinr_dB,PHY_vars_eNB_g[att_eNB_id][CC_id]->frame_parms.N_RB_DL);
}
}
} // hold channel*/
}
else { //abstraction_flag
pthread_mutex_lock(&eNB_output_mutex[UE_id]);
printf("eNB_output_mask[UE_id] is %d\n",eNB_output_mask[UE_id]);
if (eNB_output_mask[UE_id] == 0) { // This is the first eNodeB for this UE, clear the buffer
for (aa=0; aa<nb_antennas_rx; aa++) {
memset((void*)r_re_DL_f[UE_id][aa],0,(frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti)*sizeof(double));
memset((void*)r_im_DL_f[UE_id][aa],0,(frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti)*sizeof(double));
}
}
pthread_mutex_unlock(&eNB_output_mutex[UE_id]);
for (eNB_id=0; eNB_id<NB_eNB_INST; eNB_id++) {
txdataF = PHY_vars_eNB_g[eNB_id][CC_id]->common_vars.txdataF[0];
sf_offset = subframe*frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti;
for (int idx=0;idx<10;idx++) printf("dumping raw subframe %d: txdataF[%d] = (%d,%d)\n", subframe, idx, ((short*)&txdataF[0][sf_offset+idx])[0], ((short*)&txdataF[0][sf_offset+idx])[1]);
tx_pwr = dac_fixed_gain(s_re_f,
s_im_f,
txdataF,
sf_offset,
nb_antennas_tx,
frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti,
sf_offset,
frame_parms->ofdm_symbol_size,
14,
frame_parms->pdsch_config_common.referenceSignalPower, // dBm/RE
frame_parms->N_RB_DL*12);
//for (x=0;x<frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti;x++){
// fprintf(file1,"%d\t%e\t%e\n",x,s_re_f[0][x],s_im_f[0][x]);
//}
write_output("txsigFrame.m","txsF", PHY_vars_eNB_g[eNB_id][CC_id]->common_vars.txdataF[0][0],10*frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti,1,16);
for (int idx=0;idx<10;idx++) printf("dumping raw tx subframe (input) %d: s_f[%d] = (%f,%f)\n", subframe, idx, s_re_f[0][idx],s_im_f[0][idx]);
#ifdef DEBUG_SIM
LOG_D(OCM,"[SIM][DL] eNB %d (CCid %d): tx_pwr %.1f dBm/RE (target %d dBm/RE), for subframe %d\n",
eNB_id,CC_id,
10*log10(tx_pwr),
frame_parms->pdsch_config_common.referenceSignalPower,
subframe);
#endif
//eNB2UE[eNB_id][UE_id]->path_loss_dB = 0;
multipath_channel_freq(eNB2UE[eNB_id][UE_id][CC_id],s_re_f,s_im_f,r_re0_f,r_im0_f,
frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti,hold_channel);
//for (x=0;x<frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti;x++){
// fprintf(file1,"%d\t%e\t%e\t%e\t%e\n",x,s_re_f[0][x],s_im_f[0][x],r_re0_f[0][x],r_im0_f[0][x]);
//}
#ifdef DEBUG_SIM
rx_pwr = signal_energy_fp2(eNB2UE[eNB_id][UE_id][CC_id]->chF[0],
frame_parms->N_RB_DL*12+1)*(frame_parms->N_RB_DL*12+1);
LOG_D(OCM,"[SIM][DL] Channel eNB %d => UE %d (CCid %d): Channel gain %f dB (%f)\n",eNB_id,UE_id,CC_id,10*log10(rx_pwr),rx_pwr);
#endif
#ifdef DEBUG_SIM
for (i=0; i<10; i++){
LOG_D(OCM,"do_DL_sig channel(%d,%d)[%d] : (%f,%f)\n",eNB_id,UE_id,i,eNB2UE[eNB_id][UE_id][CC_id]->chF[0][i].x,eNB2UE[eNB_id][UE_id][CC_id]->chF[0][i].y);
}
for (i=frame_parms->N_RB_DL*12-10; i<frame_parms->N_RB_DL*12; i++){
LOG_D(OCM,"do_DL_sig channel(%d,%d)[%d] : (%f,%f)\n",eNB_id,UE_id,i,eNB2UE[eNB_id][UE_id][CC_id]->chF[0][i].x,eNB2UE[eNB_id][UE_id][CC_id]->chF[0][i].y);
}
#endif
LOG_D(OCM,"[SIM][DL] Channel eNB %d => UE %d (CCid %d): tx_power %.1f dBm/RE, path_loss %1.f dB\n",
eNB_id,UE_id,CC_id,
(double)frame_parms->pdsch_config_common.referenceSignalPower,
// enb_data[eNB_id]->tx_power_dBm,
eNB2UE[eNB_id][UE_id][CC_id]->path_loss_dB);
#ifdef DEBUG_SIM
rx_pwr = signal_energy_fp(r_re0_f,r_im0_f,nb_antennas_rx,
frame_parms->ofdm_symbol_size,
sf_offset)/(12.0*frame_parms->N_RB_DL);
LOG_D(OCM,"[SIM][DL] UE %d : rx_pwr %f dBm/RE (%f dBm RSSI)for subframe %d\n",UE_id,
10*log10(rx_pwr),
10*log10(rx_pwr*(double)frame_parms->N_RB_DL*12),subframe);
LOG_D(OCM,"[SIM][DL] UE %d : rx_pwr (noise) -132 dBm/RE (N0fs = %.1f dBm, N0B = %.1f dBm) for slot %d (subframe %d)\n",
UE_id,10*log10(eNB2UE[eNB_id][UE_id][CC_id]->sampling_rate*1e6)-174,
10*log10(eNB2UE[eNB_id][UE_id][CC_id]->sampling_rate*1e6*12*frame_parms->N_RB_DL/(double)frame_parms->ofdm_symbol_size)-174,
subframe);
#endif
if (eNB2UE[eNB_id][UE_id][CC_id]->first_run == 1)
eNB2UE[eNB_id][UE_id][CC_id]->first_run = 0;
// RF model
#ifdef DEBUG_SIM
LOG_D(OCM,"[SIM][DL] UE %d (CCid %d): rx_gain %d dB (-ADC %f) for subframe %d\n",UE_id,CC_id,PHY_vars_UE_g[UE_id][CC_id]->rx_total_gain_dB,
PHY_vars_UE_g[UE_id][CC_id]->rx_total_gain_dB-66.227,subframe);
#endif
rf_rx_simple(r_re0_f,
r_im0_f,
nb_antennas_rx,
frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti,
1e3/eNB2UE[eNB_id][UE_id][CC_id]->sampling_rate, // sampling time (ns)
(double)PHY_vars_UE_g[UE_id][CC_id]->rx_total_gain_dB - 66.227); // rx_gain (dB) (66.227 = 20*log10(pow2(11)) = gain from the adc that will be applied later)
#ifdef DEBUG_SIM
rx_pwr = signal_energy_fp(r_re0_f,r_im0_f,
nb_antennas_rx,
frame_parms->ofdm_symbol_size,//?
sf_offset)/(12.0*frame_parms->N_RB_DL);
LOG_D(OCM,"[SIM][DL] UE %d : ADC in (eNB %d) %f dBm/RE for subframe %d\n",
UE_id,eNB_id,
10*log10(rx_pwr),subframe);
#endif
pthread_mutex_lock(&eNB_output_mutex[UE_id]);
for (i=0; i<frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti; i++) {
for (aa=0; aa<nb_antennas_rx; aa++) {
r_re_DL_f[UE_id][aa][i]+=r_re0_f[aa][i];
r_im_DL_f[UE_id][aa][i]+=r_im0_f[aa][i];
}
}
eNB_output_mask[UE_id] |= (1<<eNB_id);
if (eNB_output_mask[UE_id] == (1<<NB_eNB_INST)-1) {
eNB_output_mask[UE_id]=0;
double *r_re_p_f[2] = {r_re_DL_f[UE_id][0],r_re_DL_f[UE_id][1]};
double *r_im_p_f[2] = {r_im_DL_f[UE_id][0],r_im_DL_f[UE_id][1]};
#ifdef DEBUG_SIM
rx_pwr0 = signal_energy_fp(r_re_p_f,r_im_p_f,nb_antennas_rx,frame_parms->ofdm_symbol_size,sf_offset)/(12.0*frame_parms->N_RB_DL);
LOG_D(OCM,"[SIM][DL] UE %d : (r_re_p_f) ADC in %f dBm for subframe %d\n",UE_id,10*log10(rx_pwr1),subframe);
LOG_D(OCM,"[SIM][DL] UE %d : ADC in %f dBm for subframe %d\n",UE_id,10*log10(rx_pwr),subframe);
#endif
for (int idx=0;idx<10;idx++) printf("dumping raw rx subframe (input) %d: rxdataF[%d] = (%f,%f)\n", subframe, idx, r_re_p_f[0][idx],r_im_p_f[0][idx]);
rxdataF = PHY_vars_UE_g[UE_id][CC_id]->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF;
sf_offset = subframe*frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti;
printf("[ch_sim] sf_offset %d\n",sf_offset);
adc(r_re_p_f,
r_im_p_f,
0,
sf_offset,
rxdataF,
nb_antennas_rx,
frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti,
12);
for (int idx=0;idx<10;idx++) printf("dumping raw rx subframe %d: rxdataF[%d] = (%d,%d)\n", subframe, idx, ((short*)&rxdataF[0][sf_offset+idx])[0], ((short*)&rxdataF[0][sf_offset+idx])[1]);
write_output("chsim_rxsigF_frame0.m","chsm_rxsF0", PHY_vars_UE_g[UE_id][CC_id]->common_vars.common_vars_rx_data_per_thread[0].rxdataF[0],10*frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti,1,16);
write_output("chsim_rxsigF_frame1.m","chsm_rxsF1", PHY_vars_UE_g[UE_id][CC_id]->common_vars.common_vars_rx_data_per_thread[1].rxdataF[0],10*frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti,1,16);
#ifdef DEBUG_SIM
rx_pwr2 = signal_energy((rxdataF[0])+sf_offset,frame_parms->ofdm_symbol_size)/(12.0*frame_parms->N_RB_DL);
LOG_D(OCM,"[SIM][DL] UE %d : rx_pwr(rxdafaF) (ADC out) %f dB/RE (%d) for subframe %d, writing to %p\n",UE_id, 10*log10((double)rx_pwr2),rx_pwr2,subframe,rxdataF);
#else
UNUSED_VARIABLE(rx_pwr2);
UNUSED_VARIABLE(tx_pwr);
UNUSED_VARIABLE(rx_pwr);
#endif
} // eNB_output_mask
pthread_mutex_unlock(&eNB_output_mutex[UE_id]);
} // eNB_id
}
}
void do_UL_sig(channel_desc_t *UE2eNB[NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX][MAX_NUM_CCs],
......@@ -567,7 +887,401 @@ void do_UL_sig(channel_desc_t *UE2eNB[NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX][MAX_N
} // abstraction_flag==0
}
void do_UL_sig_freq(channel_desc_t *UE2eNB[NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX][MAX_NUM_CCs],
node_desc_t *enb_data[NUMBER_OF_eNB_MAX],node_desc_t *ue_data[NUMBER_OF_UE_MAX],
uint16_t subframe,uint8_t abstraction_flag,LTE_DL_FRAME_PARMS *frame_parms,
uint32_t frame,int eNB_id,uint8_t CC_id)
{
printf("do_UL_sig\n");
int32_t **txdata,**txdataF,**rxdata,**rxdataF;
#ifdef PHY_ABSTRACTION_UL
int32_t att_eNB_id=-1;
#endif
uint8_t UE_id=0;
uint8_t nb_antennas_rx = UE2eNB[0][0][CC_id]->nb_rx; // number of rx antennas at eNB
uint8_t nb_antennas_tx = UE2eNB[0][0][CC_id]->nb_tx; // number of tx antennas at UE
double tx_pwr, rx_pwr;
int32_t rx_pwr2;
uint32_t i,aa;
uint32_t sf_offset;
uint8_t hold_channel=0;
#ifdef PHY_ABSTRACTION_UL
double min_path_loss=-200;
uint16_t ul_nb_rb=0 ;
uint16_t ul_fr_rb=0;
int ulnbrb2 ;
int ulfrrb2 ;
uint8_t harq_pid;
#endif
double s_re0_f[2048*14];//ofdm_symbol_size*symbols_per_tti;
double s_re1_f[2048*14];//ofdm_symbol_size*symbols_per_tti;
double *s_re_f[2];
double s_im0_f[2048*14];//ofdm_symbol_size*symbols_per_tti;
double s_im1_f[2048*14];//ofdm_symbol_size*symbols_per_tti;
double *s_im_f[2];
double r_re00_f[2048*14];//ofdm_symbol_size*symbols_per_tti;
double r_re01_f[2048*14];//ofdm_symbol_size*symbols_per_tti;
double *r_re0_f[2];
double r_im00_f[2048*14];//ofdm_symbol_size*symbols_per_tti;
double r_im01_f[2048*14];//ofdm_symbol_size*symbols_per_tti;
double *r_im0_f[2];
s_re_f[0] = s_re0_f;
s_im_f[0] = s_im0_f;
s_re_f[1] = s_re1_f;
s_im_f[1] = s_im1_f;
r_re0_f[0] = r_re00_f;
r_im0_f[0] = r_im00_f;
r_re0_f[1] = r_re01_f;
r_im0_f[1] = r_im01_f;
uint8_t do_ofdm_mod = PHY_vars_UE_g[0][0]->do_ofdm_mod;
if (abstraction_flag!=0) {
#ifdef PHY_ABSTRACTION_UL
for (UE_id=0; UE_id<NB_UE_INST; UE_id++) {
if (!hold_channel) {
random_channel(UE2eNB[UE_id][eNB_id][CC_id],abstraction_flag);
freq_channel(UE2eNB[UE_id][eNB_id][CC_id], frame_parms->N_RB_UL,frame_parms->N_RB_UL*12+1);
// REceived power at the eNB
rx_pwr = signal_energy_fp2(UE2eNB[UE_id][eNB_id][CC_id]->ch[0],
UE2eNB[UE_id][eNB_id][CC_id]->channel_length)*UE2eNB[UE_id][att_eNB_id][CC_id]->channel_length; // calculate the rx power at the eNB
}
// write_output_xrange("SINRch.m","SINRch",PHY_vars_eNB_g[att_eNB_id]->sinr_dB_eNB,frame_parms->N_RB_UL*12+1,1,1);
if(subframe>1 && subframe <5) {
harq_pid = subframe2harq_pid(frame_parms,frame,subframe);
ul_nb_rb = PHY_vars_eNB_g[att_eNB_id][CC_id]->ulsch_eNB[(uint8_t)UE_id]->harq_processes[harq_pid]->nb_rb;
ul_fr_rb = PHY_vars_eNB_g[att_eNB_id][CC_id]->ulsch_eNB[(uint8_t)UE_id]->harq_processes[harq_pid]->first_rb;
}
if(ul_nb_rb>1 && (ul_fr_rb < 25 && ul_fr_rb > -1)) {
number_rb_ul = ul_nb_rb;
first_rbUL = ul_fr_rb;
init_snr_up(UE2eNB[UE_id][att_eNB_id][CC_id],enb_data[att_eNB_id], ue_data[UE_id],PHY_vars_eNB_g[att_eNB_id][CC_id]->sinr_dB,&PHY_vars_UE_g[att_eNB_id][CC_id]->N0,ul_nb_rb,ul_fr_rb);
}
} //UE_id
#else
#endif
} else { //without abstraction
pthread_mutex_lock(&UE_output_mutex[eNB_id]);
// Clear RX signal for eNB = eNB_id
for (i=0; i<frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti; i++) {
for (aa=0; aa<nb_antennas_rx; aa++) {
r_re_UL_f[eNB_id][aa][i]=0.0;
r_im_UL_f[eNB_id][aa][i]=0.0;
}
}
pthread_mutex_unlock(&UE_output_mutex[eNB_id]);
// Compute RX signal for eNB = eNB_id
for (UE_id=0; UE_id<NB_UE_INST; UE_id++) {
txdataF = PHY_vars_UE_g[UE_id][CC_id]->common_vars.txdataF;
sf_offset = subframe*frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti;
if (((double)PHY_vars_UE_g[UE_id][CC_id]->tx_power_dBm[subframe] +
UE2eNB[UE_id][eNB_id][CC_id]->path_loss_dB) <= -125.0) {
// don't simulate a UE that is too weak
LOG_D(OCM,"[SIM][UL] UE %d tx_pwr %d dBm (num_RE %d) for subframe %d (sf_offset %d)\n",
UE_id,
PHY_vars_UE_g[UE_id][CC_id]->tx_power_dBm[subframe],
PHY_vars_UE_g[UE_id][CC_id]->tx_total_RE[subframe],
subframe,sf_offset);
printf("multipath_channel, UE too weak %e\n", ((double)PHY_vars_UE_g[UE_id][CC_id]->tx_power_dBm[subframe] +
UE2eNB[UE_id][eNB_id][CC_id]->path_loss_dB));
} else {
tx_pwr = dac_fixed_gain((double**)s_re_f,
(double**)s_im_f,
txdataF,
sf_offset,
nb_antennas_tx,
frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti,
sf_offset,
frame_parms->ofdm_symbol_size,
frame_parms->symbols_per_tti,
(double)PHY_vars_UE_g[UE_id][CC_id]->tx_power_dBm[subframe]-10*log10((double)PHY_vars_UE_g[UE_id][CC_id]->tx_total_RE[subframe]),
PHY_vars_UE_g[UE_id][CC_id]->tx_total_RE[subframe]); // This make the previous argument the total power
LOG_D(OCM,"[SIM][UL] UE %d tx_pwr %f dBm (target %d dBm, num_RE %d) for subframe %d (sf_offset %d)\n",
UE_id,
10*log10(tx_pwr),
PHY_vars_UE_g[UE_id][CC_id]->tx_power_dBm[subframe],
PHY_vars_UE_g[UE_id][CC_id]->tx_total_RE[subframe],
subframe,sf_offset);
multipath_channel_freq(UE2eNB[UE_id][eNB_id][CC_id],s_re_f,s_im_f,r_re0_f,r_im0_f,
frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti,hold_channel);
//write_output("txprachF.m","prach_txF", PHY_vars_UE_g[0][0]->prach_vars[0]->prachF,frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti,1,1);
rx_pwr = signal_energy_fp2(UE2eNB[UE_id][eNB_id][CC_id]->ch[0],UE2eNB[UE_id][eNB_id][CC_id]->channel_length)*UE2eNB[UE_id][eNB_id][CC_id]->channel_length;
#ifdef DEBUG_SIM
for (i=0; i<10; i++){
LOG_D(OCM,"do_UL_sig channel(%d,%d)[%d] : (%f,%f)\n",UE_id,eNB_id,i,UE2eNB[UE_id][eNB_id][CC_id]->ch[0][i].x,UE2eNB[UE_id][eNB_id][CC_id]->ch[0][i].y);
}
for (i=frame_parms->N_RB_DL*12-10; i<frame_parms->N_RB_DL*12; i++){
LOG_D(OCM,"do_UL_sig channel(%d,%d)[%d] : (%f,%f)\n",UE_id,eNB_id,i,UE2eNB[UE_id][eNB_id][CC_id]->ch[0][i].x,UE2eNB[UE_id][eNB_id][CC_id]->ch[0][i].y);
}
#endif
LOG_D(OCM,"[SIM][UL] subframe %d Channel UE %d => eNB %d : %f dB (hold %d,length %d, PL %f)\n",subframe,UE_id,eNB_id,10*log10(rx_pwr),
hold_channel,12*frame_parms->N_RB_DL+1,
UE2eNB[UE_id][eNB_id][CC_id]->path_loss_dB);
rx_pwr = signal_energy_fp(r_re0_f,r_im0_f,nb_antennas_rx,frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti,0);
LOG_D(OCM,"[SIM][UL] eNB %d : rx_pwr %f dBm (%f) for subframe %d, sptti %d\n",
eNB_id,10*log10(rx_pwr),rx_pwr,subframe,frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti);
if (UE2eNB[UE_id][eNB_id][CC_id]->first_run == 1)
UE2eNB[UE_id][eNB_id][CC_id]->first_run = 0;
pthread_mutex_lock(&UE_output_mutex[eNB_id]);
for (aa=0; aa<nb_antennas_rx; aa++) {
for (i=0; i<frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti; i++) {
r_re_UL_f[eNB_id][aa][i]+=r_re0_f[aa][i];
r_im_UL_f[eNB_id][aa][i]+=r_im0_f[aa][i];
}
}
pthread_mutex_unlock(&UE_output_mutex[eNB_id]);
}
} //UE_id
double *r_re_p_f[2] = {r_re_UL_f[eNB_id][0],r_re_UL_f[eNB_id][1]};
double *r_im_p_f[2] = {r_im_UL_f[eNB_id][0],r_im_UL_f[eNB_id][1]};
rf_rx_simple(r_re_p_f,
r_im_p_f,
nb_antennas_rx,
frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti,
1e3/UE2eNB[0][eNB_id][CC_id]->sampling_rate, // sampling time (ns)
(double)PHY_vars_eNB_g[eNB_id][CC_id]->rx_total_gain_dB - 66.227); // rx_gain (dB) (66.227 = 20*log10(pow2(11)) = gain from the adc that will be applied later)
#ifdef DEBUG_SIM
rx_pwr = signal_energy_fp(r_re_p_f,r_im_p_f,nb_antennas_rx,frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti,0)*(double)frame_parms->ofdm_symbol_size/(12.0*frame_parms->N_RB_DL);
LOG_D(OCM,"[SIM][UL] rx_pwr (ADC in) %f dB for subframe %d\n",10*log10(rx_pwr),subframe);
#endif
rxdataF = PHY_vars_eNB_g[eNB_id][CC_id]->common_vars.rxdataF[0];
sf_offset = subframe*frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti;
adc(r_re_p_f,
r_im_p_f,
0,
sf_offset,
rxdataF,
nb_antennas_rx,
subframe*frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti,
12);
#ifdef DEBUG_SIM
//rx_pwr2 = signal_energy(rxdataF[0]+sf_offset,subframe*frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti)*(double)frame_parms->ofdm_symbol_size/(12.0*frame_parms->N_RB_DL);
//LOG_D(OCM,"[SIM][UL] eNB %d rx_pwr (ADC out) %f dB (%d) for subframe %d (offset %d)\n",eNB_id,10*log10((double)rx_pwr2),rx_pwr2,subframe,sf_offset);
#else
UNUSED_VARIABLE(tx_pwr);
UNUSED_VARIABLE(rx_pwr);
UNUSED_VARIABLE(rx_pwr2);
#endif
} // abstraction_flag==0
}
void do_UL_prach(channel_desc_t *UE2eNB[NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX][MAX_NUM_CCs],
node_desc_t *enb_data[NUMBER_OF_eNB_MAX],node_desc_t *ue_data[NUMBER_OF_UE_MAX],
uint16_t subframe,uint8_t abstraction_flag,LTE_DL_FRAME_PARMS *frame_parms,
uint32_t frame,int eNB_id,uint8_t CC_id)
{
//int32_t **txdata,**txdataF,**rxdata,**rxdataF;
#ifdef PHY_ABSTRACTION_UL
int32_t att_eNB_id=-1;
#endif
uint8_t UE_id=0;
int16_t *rx_prachF;
int16_t *tx_prachF;
uint8_t nb_antennas_rx = UE2eNB[0][0][CC_id]->nb_rx; // number of rx antennas at eNB
uint8_t nb_antennas_tx = UE2eNB[0][0][CC_id]->nb_tx; // number of tx antennas at UE
double tx_pwr, rx_pwr;
int32_t rx_pwr2;
uint32_t i,aa;
uint32_t sf_offset;
uint8_t hold_channel=0;
#ifdef PHY_ABSTRACTION_UL
double min_path_loss=-200;
uint16_t ul_nb_rb=0 ;
uint16_t ul_fr_rb=0;
int ulnbrb2 ;
int ulfrrb2 ;
uint8_t harq_pid;
#endif
double s_re0_f[2048*14*12];//ofdm_symbol_size*symbols_per_tti;
double s_re1_f[2048*14*12];//ofdm_symbol_size*symbols_per_tti;
double *s_re_f[2];
double s_im0_f[2048*14*12];//ofdm_symbol_size*symbols_per_tti;
double s_im1_f[2048*14*12];//ofdm_symbol_size*symbols_per_tti;
double *s_im_f[2];
double r_re00_f[2048*14*12];//ofdm_symbol_size*symbols_per_tti;
double r_re01_f[2048*14*12];//ofdm_symbol_size*symbols_per_tti;
double *r_re0_f[2];
double r_im00_f[2048*14*12];//ofdm_symbol_size*symbols_per_tti;
double r_im01_f[2048*14*12];//ofdm_symbol_size*symbols_per_tti;
double *r_im0_f[2];
s_re_f[0] = s_re0_f;
s_im_f[0] = s_im0_f;
s_re_f[1] = s_re1_f;
s_im_f[1] = s_im1_f;
r_re0_f[0] = r_re00_f;
r_im0_f[0] = r_im00_f;
r_re0_f[1] = r_re01_f;
r_im0_f[1] = r_im01_f;
if (abstraction_flag!=0) {
#ifdef PHY_ABSTRACTION_UL
LOG_D(OCM,"[SIM][UL] UE %d, Abstraction for do_UL_prach is not implemented in frequency domain\n",UE_id);
exit(1);
#else
#endif
} else { //without abstraction
pthread_mutex_lock(&UE_output_mutex[eNB_id]);
// Clear RX signal for eNB = eNB_id
for (i=0; i<frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti*12; i++) {
for (aa=0; aa<nb_antennas_rx; aa++) {
r_re_UL_f_prach[eNB_id][aa][i]=0.0;
r_im_UL_f_prach[eNB_id][aa][i]=0.0;
}
}
pthread_mutex_unlock(&UE_output_mutex[eNB_id]);
// Compute RX signal for eNB = eNB_id
for (UE_id=0; UE_id<NB_UE_INST; UE_id++) {
tx_prachF = PHY_vars_UE_g[UE_id][CC_id]->prach_vars[eNB_id]->prachF;
//write_output("txprachF.m","prach_txF", PHY_vars_UE_g[0][0]->prach_vars[0]->prachF,frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti*12,1,1);
sf_offset = subframe*frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti*12;
if (((double)PHY_vars_UE_g[UE_id][CC_id]->tx_power_dBm[subframe] +
UE2eNB[UE_id][eNB_id][CC_id]->path_loss_dB) <= -125.0) {
// don't simulate a UE that is too weak
LOG_D(OCM,"[SIM][UL] UE %d tx_pwr %d dBm (num_RE %d) for subframe %d (sf_offset %d)\n",
UE_id,
PHY_vars_UE_g[UE_id][CC_id]->tx_power_dBm[subframe],
PHY_vars_UE_g[UE_id][CC_id]->tx_total_RE[subframe],
subframe,sf_offset);
printf("multipath_channel_prach, UE too weak %e\n", ((double)PHY_vars_UE_g[UE_id][CC_id]->tx_power_dBm[subframe] +
UE2eNB[UE_id][eNB_id][CC_id]->path_loss_dB));
} else {
printf("multipath_channel_prach\n");
tx_pwr = dac_fixed_gain_prach((double**)s_re_f,
(double**)s_im_f,
(uint32_t*)tx_prachF,
sf_offset,
nb_antennas_tx,
frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti*12,
sf_offset,
frame_parms->ofdm_symbol_size*12,
frame_parms->symbols_per_tti,
(double)PHY_vars_UE_g[UE_id][CC_id]->tx_power_dBm[subframe]-10*log10((double)PHY_vars_UE_g[UE_id][CC_id]->tx_total_RE[subframe]),
PHY_vars_UE_g[UE_id][CC_id]->tx_total_RE[subframe]); // This make the previous argument the total power
LOG_D(OCM,"[SIM][UL] UE %d tx_pwr %f dBm (target %d dBm, num_RE %d) for subframe %d (sf_offset %d)\n",
UE_id,
10*log10(tx_pwr),
PHY_vars_UE_g[UE_id][CC_id]->tx_power_dBm[subframe],
PHY_vars_UE_g[UE_id][CC_id]->tx_total_RE[subframe],
subframe,sf_offset);
// write_output("s_re_f.m","s_re_f_txF", s_re_f,frame_parms->ofdm_symbol_size*12,1,1);
multipath_channel_prach(UE2eNB[UE_id][eNB_id][CC_id],s_re_f,s_im_f,r_re0_f,r_im0_f,
frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti*12,hold_channel);
//write_output("txprachF.m","prach_txF", PHY_vars_UE_g[0][0]->prach_vars[0]->prachF,frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti,1,1);
rx_pwr = signal_energy_fp2(UE2eNB[UE_id][eNB_id][CC_id]->chF[0],(12*frame_parms->N_RB_DL+1))*(12*frame_parms->N_RB_DL+1);
LOG_D(OCM,"[SIM][UL] subframe %d Channel UE %d => eNB %d : %f dB (hold %d,length %d, PL %f)\n",subframe,UE_id,eNB_id,10*log10(rx_pwr),
hold_channel,12*frame_parms->N_RB_DL+1,
UE2eNB[UE_id][eNB_id][CC_id]->path_loss_dB);
rx_pwr = signal_energy_fp(r_re0_f,r_im0_f,nb_antennas_rx,frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti*12,0);
LOG_D(OCM,"[SIM][UL] eNB %d : rx_pwr %f dBm (%f) for subframe %d, sptti %d\n",
eNB_id,10*log10(rx_pwr),rx_pwr,subframe,frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti*12);
#ifdef DEBUG_SIM
for (i=0; i<864; i++)
LOG_D(OCM,"do_UL_prach channel(%d,%d)[%d] : (%f,%f)\n",UE_id,eNB_id,i,UE2eNB[UE_id][eNB_id][CC_id]->ch[0][i].x,UE2eNB[UE_id][eNB_id][CC_id]->ch[0][i].y);
#endif
//for (i=0; i<864; i++){
// LOG_D(OCM,"channel_prach(%d,%d)[%d] : (%f,%f)\n",eNB_id,UE_id,i,UE2eNB[UE_id][eNB_id][CC_id]->chF[0][i].x,UE2eNB[UE_id][eNB_id][CC_id]->chF[0][i].y);
//}
if (UE2eNB[UE_id][eNB_id][CC_id]->first_run == 1)
UE2eNB[UE_id][eNB_id][CC_id]->first_run = 0;
pthread_mutex_lock(&UE_output_mutex[eNB_id]);
for (aa=0; aa<nb_antennas_rx; aa++) {
for (i=0; i<frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti; i++) {
r_re_UL_f_prach[eNB_id][aa][i]+=r_re0_f[aa][i];
r_im_UL_f_prach[eNB_id][aa][i]+=r_im0_f[aa][i];
}
}
pthread_mutex_unlock(&UE_output_mutex[eNB_id]);
}
} //UE_id
double *r_re_p_f[2] = {r_re_UL_f_prach[eNB_id][0],r_re_UL_f_prach[eNB_id][1]};
double *r_im_p_f[2] = {r_im_UL_f_prach[eNB_id][0],r_im_UL_f_prach[eNB_id][1]};
rf_rx_simple(r_re_p_f,
r_im_p_f,
nb_antennas_rx,
frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti*12,
1e3/UE2eNB[0][eNB_id][CC_id]->sampling_rate, // sampling time (ns)
(double)PHY_vars_eNB_g[eNB_id][CC_id]->rx_total_gain_dB - 66.227); // rx_gain (dB) (66.227 = 20*log10(pow2(11)) = gain from the adc that will be applied later)
#ifdef DEBUG_SIM
rx_pwr = signal_energy_fp(r_re_p_f,r_im_p_f,nb_antennas_rx,frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti*12,0)*(double)frame_parms->ofdm_symbol_size/(12.0*frame_parms->N_RB_DL);
LOG_D(OCM,"[SIM][UL] rx_pwr (ADC in) %f dB for subframe %d\n",10*log10(rx_pwr),subframe);
#endif
rx_prachF = PHY_vars_eNB_g[eNB_id][CC_id]->prach_vars.prachF;
sf_offset = subframe*frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti*12;
adc_prach(r_re_p_f,
r_im_p_f,
0,
sf_offset,
(unsigned int*)rx_prachF,
nb_antennas_rx,
subframe*frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti*12,
12);
//write_output("rxprachF.m","prach_rxF", &PHY_vars_eNB_g[eNB_id][CC_id]->prach_vars.prachF[0],frame_parms->ofdm_symbol_size*12,1,1);
#ifdef DEBUG_SIM
//rx_pwr2 = signal_energy(rxdataF[0]+sf_offset,subframe*frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti)*(double)frame_parms->ofdm_symbol_size/(12.0*frame_parms->N_RB_DL);
//LOG_D(OCM,"[SIM][UL] eNB %d rx_pwr (ADC out) %f dB (%d) for subframe %d (offset %d)\n",eNB_id,10*log10((double)rx_pwr2),rx_pwr2,subframe,sf_offset);
#else
UNUSED_VARIABLE(tx_pwr);
UNUSED_VARIABLE(rx_pwr);
UNUSED_VARIABLE(rx_pwr2);
#endif
} // abstraction_flag==0
}
void init_channel_vars(LTE_DL_FRAME_PARMS *frame_parms, double ***s_re,double ***s_im,double ***r_re,double ***r_im,double ***r_re0,double ***r_im0)
{
......@@ -583,4 +1297,39 @@ void init_channel_vars(LTE_DL_FRAME_PARMS *frame_parms, double ***s_re,double **
pthread_mutex_init(&UE_output_mutex[i],NULL);
}
void init_channel_vars_freq(LTE_DL_FRAME_PARMS *frame_parms, double ***s_re_f,double ***s_im_f,double ***r_re_f,double ***r_im_f,double ***r_re0_f,double ***r_im0_f)
{
int i,j,eNB_id,UE_id,CC_id,th_id;
memset(eNB_output_mask,0,sizeof(int)*NUMBER_OF_UE_MAX);
for (i=0;i<NB_UE_INST;i++)
pthread_mutex_init(&eNB_output_mutex[i],NULL);
memset(UE_output_mask,0,sizeof(int)*NUMBER_OF_eNB_MAX);
for (i=0;i<NB_eNB_INST;i++)
pthread_mutex_init(&UE_output_mutex[i],NULL);
// Channel estimates initialization
for (UE_id=0;UE_id<NB_UE_INST;UE_id++){
for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++){
// Channel estimates
for (eNB_id=0; eNB_id<NB_UE_INST; eNB_id++) {
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
PHY_vars_UE_g[UE_id][CC_id]->common_vars.common_vars_rx_data_per_thread[th_id].dl_ch_estimates[eNB_id] = (int32_t**)malloc16_clear(8*sizeof(int32_t*));
}
for (i=0; i<frame_parms->nb_antennas_rx; i++)
for (j=0; j<4; j++) {
int idx = (j<<1) + i;
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
PHY_vars_UE_g[UE_id][CC_id]->common_vars.common_vars_rx_data_per_thread[th_id].dl_ch_estimates[eNB_id][idx] = (int32_t*)malloc16_clear( sizeof(int32_t)*frame_parms->symbols_per_tti*(frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH) );
}
}
}
}
}
}
......@@ -767,14 +767,21 @@ l2l1_task (void *args_p)
< (oai_emulation.info.first_enb_local
+ oai_emulation.info.nb_enb_local));
eNB_inst++) {
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++)
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++){
if (PHY_vars_UE_g[0][0]->do_ofdm_mod)//frequency analysis
current_eNB_rx_timestamp[eNB_inst][CC_id] += PHY_vars_eNB_g[eNB_inst][CC_id]->frame_parms.ofdm_symbol_size*PHY_vars_eNB_g[eNB_inst][CC_id]->frame_parms.symbols_per_tti;
else//time analysis
current_eNB_rx_timestamp[eNB_inst][CC_id] += PHY_vars_eNB_g[eNB_inst][CC_id]->frame_parms.samples_per_tti;
}
}
for (UE_inst = 0; UE_inst<NB_UE_INST;UE_inst++) {
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++)
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++){
if (PHY_vars_UE_g[0][0]->do_ofdm_mod)//frequency analysis
current_UE_rx_timestamp[UE_inst][CC_id] += PHY_vars_UE_g[UE_inst][CC_id]->frame_parms.ofdm_symbol_size*PHY_vars_UE_g[UE_inst][CC_id]->frame_parms.symbols_per_tti;
else//time analysis
current_UE_rx_timestamp[UE_inst][CC_id] += PHY_vars_UE_g[UE_inst][CC_id]->frame_parms.samples_per_tti;
}
}
for (eNB_inst = oai_emulation.info.first_enb_local;
(eNB_inst
< (oai_emulation.info.first_enb_local
......
......@@ -122,6 +122,7 @@ int map1,map2;
double **ShaF = NULL;
// pointers signal buffers (s = transmit, r,r0 = receive)
double **s_re, **s_im, **r_re, **r_im, **r_re0, **r_im0;
double **s_re_f, **s_im_f, **r_re_f, **r_im_f, **r_re0_f, **r_im0_f;
node_list* ue_node_list = NULL;
node_list* enb_node_list = NULL;
int omg_period = 10000;
......@@ -1050,6 +1051,17 @@ int eNB_trx_read(openair0_device *device, openair0_timestamp *ptimestamp, void *
*ptimestamp = last_eNB_rx_timestamp[eNB_id][CC_id];
int do_ofdm_mod = PHY_vars_UE_g[0][CC_id]->do_ofdm_mod;
LTE_DL_FRAME_PARMS *frame_parms=&PHY_vars_UE_g[0][CC_id]->frame_parms;
uint32_t frame;
if (do_ofdm_mod)
LOG_D(EMU,"eNB_trx_read nsamps %d TS(%"PRId64",%"PRId64") => subframe %d\n",nsamps,
current_eNB_rx_timestamp[eNB_id][CC_id],
last_eNB_rx_timestamp[eNB_id][CC_id],
(int)((*ptimestamp/(PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.ofdm_symbol_size*PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.symbols_per_tti))%10));
else
LOG_D(EMU,"eNB_trx_read nsamps %d TS(%"PRId64",%"PRId64") => subframe %d\n",nsamps,
current_eNB_rx_timestamp[eNB_id][CC_id],
last_eNB_rx_timestamp[eNB_id][CC_id],
......@@ -1071,13 +1083,48 @@ int eNB_trx_read(openair0_device *device, openair0_timestamp *ptimestamp, void *
nsamps -= read_samples;
if (current_eNB_rx_timestamp[eNB_id][CC_id] == last) {
subframe = (last/PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.samples_per_tti)%10;
//subframe = (subframe+9) % 10;
if (do_ofdm_mod)
{
subframe = (last/(PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.ofdm_symbol_size*PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.symbols_per_tti))%10;
frame = (last/(10*PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.ofdm_symbol_size*PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.symbols_per_tti))%1023;
}
else
{
subframe = (last/PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.samples_per_tti)%10;
frame = (last/(10*PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.samples_per_tti))%1023;
}
printf("[oaisim_functs] subframe %d, frame %d\n",subframe,frame);
LOG_D(PHY,"eNB_trx_read generating UL subframe %d (Ts %llu, current TS %llu)\n",
subframe,(unsigned long long)*ptimestamp,
(unsigned long long)current_eNB_rx_timestamp[eNB_id][CC_id]);
if (do_ofdm_mod)
{
write_output("txprachF.m","prach_txF", PHY_vars_UE_g[0][0]->prach_vars[0]->prachF,frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti,1,1);
//generate_prach(PHY_vars_UE_g[0][0],eNB_id,subframe,frame);
//PHY_vars_UE_g[0][0]->generate_prach=1;
if (is_prach_subframe(frame_parms,frame,subframe))
do_UL_prach(UE2eNB,
enb_data,
ue_data,
subframe,
0, // abstraction_flag
&PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms,
0, // frame is only used for abstraction
eNB_id,
CC_id);
do_UL_sig_freq(UE2eNB,
enb_data,
ue_data,
subframe,
0, // abstraction_flag
&PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms,
0, // frame is only used for abstraction
eNB_id,
CC_id);
}
else
do_UL_sig(UE2eNB,
enb_data,
ue_data,
......@@ -1102,12 +1149,14 @@ int UE_trx_read(openair0_device *device, openair0_timestamp *ptimestamp, void **
int ret = nsamps;
int UE_id = device->Mod_id;
int CC_id = device->CC_id;
int subframe;
int subframe, frame;
int read_samples, max_samples;
openair0_timestamp last = last_UE_rx_timestamp[UE_id][CC_id];
*ptimestamp = last_UE_rx_timestamp[UE_id][CC_id];
int do_ofdm_mod = PHY_vars_UE_g[0][0]->do_ofdm_mod;
LOG_D(EMU,"UE_trx_read nsamps %d TS(%llu,%llu) antenna %d\n",nsamps,
(unsigned long long)current_UE_rx_timestamp[UE_id][CC_id],
(unsigned long long)last_UE_rx_timestamp[UE_id][CC_id],
......@@ -1143,13 +1192,32 @@ int UE_trx_read(openair0_device *device, openair0_timestamp *ptimestamp, void **
if (current_UE_rx_timestamp[UE_id][CC_id] == last) {
// we have one subframe here so generate the received signal
if (do_ofdm_mod)
{
subframe = (last/(PHY_vars_UE_g[UE_id][CC_id]->frame_parms.ofdm_symbol_size*PHY_vars_UE_g[UE_id][CC_id]->frame_parms.symbols_per_tti))%10;
frame = (last/(10*PHY_vars_UE_g[UE_id][CC_id]->frame_parms.ofdm_symbol_size*PHY_vars_UE_g[UE_id][CC_id]->frame_parms.symbols_per_tti))%1023;
}
else
{
subframe = (last/PHY_vars_UE_g[UE_id][CC_id]->frame_parms.samples_per_tti)%10;
frame = (last/(10*PHY_vars_UE_g[UE_id][CC_id]->frame_parms.samples_per_tti))%1023;
}
printf("[oaisim_functs] subframe %d, frame %d\n",subframe,frame);
//subframe = (subframe+9) % 10;
LOG_D(PHY,"UE_trx_read generating DL subframe %d (Ts %llu, current TS %llu)\n",
subframe,(unsigned long long)*ptimestamp,
(unsigned long long)current_UE_rx_timestamp[UE_id][CC_id]);
if (do_ofdm_mod)
do_DL_sig_freq(eNB2UE,
enb_data,
ue_data,
subframe,
0, //abstraction_flag,
&PHY_vars_UE_g[UE_id][CC_id]->frame_parms,
UE_id,
CC_id);
else
do_DL_sig(eNB2UE,
enb_data,
ue_data,
......@@ -1273,6 +1341,9 @@ void init_devices(void){
PHY_vars_eNB_g[eNB_id][CC_id]->rfdevice.trx_stop_func = eNB_trx_stop;
PHY_vars_eNB_g[eNB_id][CC_id]->rfdevice.trx_set_freq_func = eNB_trx_set_freq;
PHY_vars_eNB_g[eNB_id][CC_id]->rfdevice.trx_set_gains_func = eNB_trx_set_gains;
if (PHY_vars_UE_g[0][0]->do_ofdm_mod)
current_eNB_rx_timestamp[eNB_id][CC_id] = PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.ofdm_symbol_size*PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.symbols_per_tti;
else
current_eNB_rx_timestamp[eNB_id][CC_id] = PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.samples_per_tti;
last_eNB_rx_timestamp[eNB_id][CC_id] = 0;
}
......@@ -1286,6 +1357,9 @@ void init_devices(void){
PHY_vars_UE_g[UE_id][CC_id]->rfdevice.trx_stop_func = UE_trx_stop;
PHY_vars_UE_g[UE_id][CC_id]->rfdevice.trx_set_freq_func = UE_trx_set_freq;
PHY_vars_UE_g[UE_id][CC_id]->rfdevice.trx_set_gains_func = UE_trx_set_gains;
if (PHY_vars_UE_g[0][0]->do_ofdm_mod)
current_UE_rx_timestamp[UE_id][CC_id] = PHY_vars_UE_g[UE_id][CC_id]->frame_parms.ofdm_symbol_size*PHY_vars_UE_g[UE_id][CC_id]->frame_parms.symbols_per_tti;
else
current_UE_rx_timestamp[UE_id][CC_id] = PHY_vars_UE_g[UE_id][CC_id]->frame_parms.samples_per_tti;
last_UE_rx_timestamp[UE_id][CC_id] = 0;
......@@ -1485,6 +1559,11 @@ void init_ocm(void)
char* frame_type = "unknown";
int do_ofdm_mod = PHY_vars_UE_g[0][0]->do_ofdm_mod;
int nb_rb, n_samples;
nb_rb=PHY_vars_UE_g[0][0]->frame_parms.N_RB_DL;
n_samples=nb_rb*12+1;
switch (oai_emulation.info.frame_type[0]) {
case FDD:
frame_type = "FDD";
......@@ -1537,6 +1616,10 @@ void init_ocm(void)
}
if (abstraction_flag == 0)
if (do_ofdm_mod)
init_channel_vars_freq (frame_parms[0], &s_re_f, &s_im_f, &r_re_f, &r_im_f, &r_re0_f, &r_im0_f);
else
init_channel_vars (frame_parms[0], &s_re, &s_im, &r_re, &r_im, &r_re0, &r_im0);
// initialize channel descriptors
......@@ -1556,7 +1639,15 @@ void init_ocm(void)
forgetting_factor,
0,
0);
if (do_ofdm_mod)
{
random_channel(eNB2UE[eNB_id][UE_id][CC_id],abstraction_flag);//Find a(l)
freq_channel(eNB2UE[eNB_id][UE_id][CC_id],nb_rb,n_samples);//Find desc->chF
}
else
random_channel(eNB2UE[eNB_id][UE_id][CC_id],abstraction_flag);
LOG_D(OCM,"[SIM] Initializing channel (%s, %d) from UE %d to eNB %d\n", oai_emulation.environment_system_config.fading.small_scale.selected_option,
map_str_to_int(small_scale_names, oai_emulation.environment_system_config.fading.small_scale.selected_option),UE_id, eNB_id);
......@@ -1569,7 +1660,12 @@ void init_ocm(void)
forgetting_factor,
0,
0);
if (do_ofdm_mod)
{
random_channel(UE2eNB[UE_id][eNB_id][CC_id],abstraction_flag);//Find a(l)
freq_channel(UE2eNB[UE_id][eNB_id][CC_id],nb_rb,n_samples);//Find desc->chF
}
else
random_channel(UE2eNB[UE_id][eNB_id][CC_id],abstraction_flag);
// to make channel reciprocal uncomment following line instead of previous. However this only works for SISO at the moment. For MIMO the channel would need to be transposed.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment