示例#1
0
int lte_est_freq_offset(int **dl_ch_estimates,
			LTE_DL_FRAME_PARMS *frame_parms,
			int l,
			int* freq_offset) {

  int ch_offset, omega, dl_ch_shift; 
  struct complex16 *omega_cpx; 
  double phase_offset;
  int freq_offset_est;
  unsigned char aa;
  s16 *dl_ch,*dl_ch_prev;
  static int first_run = 1;
  int coef = 1<<10;
  int ncoef =  32767 - coef;


  ch_offset = (l*(frame_parms->ofdm_symbol_size));
 
  if ((l!=0) && (l!=(4-frame_parms->Ncp))) {
    msg("lte_est_freq_offset: l (%d) must be 0 or %d\n",l,4-frame_parms->Ncp);
    return(-1);
  }

  phase_offset = 0.0;

  //  for (aa=0;aa<frame_parms->nb_antennas_rx*frame_parms->nb_antennas_tx;aa++) {
  for (aa=0;aa<1;aa++) {
    
    dl_ch = (s16 *)&dl_ch_estimates[aa][12+ch_offset];
    
    dl_ch_shift = 4+(log2_approx(dl_channel_level(dl_ch,frame_parms))/2);
    //    printf("dl_ch_shift: %d\n",dl_ch_shift);
    
    if (ch_offset == 0)
      dl_ch_prev = (s16 *)&dl_ch_estimates[aa][12+(4-frame_parms->Ncp)*(frame_parms->ofdm_symbol_size)];
    else
      dl_ch_prev = (s16 *)&dl_ch_estimates[aa][12+0];
    
    
    // calculate omega = angle(conj(dl_ch)*dl_ch_prev))
    //    printf("Computing freq_offset\n");
    omega = dot_product(dl_ch,dl_ch_prev,(frame_parms->N_RB_DL/2 - 1)*12,dl_ch_shift);
    //omega = dot_product(dl_ch,dl_ch_prev,frame_parms->ofdm_symbol_size,15);
    omega_cpx = (struct complex16*) &omega;
    
    //    printf("omega (%d,%d)\n",omega_cpx->r,omega_cpx->i);
    
    dl_ch = (s16 *)&dl_ch_estimates[aa][(((frame_parms->N_RB_DL/2) + 1)*12) + ch_offset];
    if (ch_offset == 0)
      dl_ch_prev = (s16 *)&dl_ch_estimates[aa][(((frame_parms->N_RB_DL/2) + 1)*12)+(4-frame_parms->Ncp)*(frame_parms->ofdm_symbol_size)];
    else
      dl_ch_prev = (s16 *)&dl_ch_estimates[aa][((frame_parms->N_RB_DL/2) + 1)*12];
    
    // calculate omega = angle(conj(dl_ch)*dl_ch_prev))
    omega = dot_product(dl_ch,dl_ch_prev,((frame_parms->N_RB_DL/2) - 1)*12,dl_ch_shift);
    omega_cpx->r += ((struct complex16*) &omega)->r;
    omega_cpx->i += ((struct complex16*) &omega)->i;
    //    phase_offset += atan2((double)omega_cpx->i,(double)omega_cpx->r);
    phase_offset += atan2((double)omega_cpx->i,(double)omega_cpx->r);
    //    printf("omega (%d,%d) -> %f\n",omega_cpx->r,omega_cpx->i,phase_offset);
  }
    //  phase_offset /= (frame_parms->nb_antennas_rx*frame_parms->nb_antennas_tx);

  freq_offset_est = (int) (phase_offset/(2*M_PI)/2.5e-4); //2.5e-4 is the time between pilot symbols
  //  printf("symbol %d : freq_offset_est %d\n",l,freq_offset_est);

  // update freq_offset with phase_offset using a moving average filter
  if (first_run == 1) {
    *freq_offset = freq_offset_est;
    first_run = 0;
  }
  else
    *freq_offset = ((freq_offset_est * coef) + (*freq_offset * ncoef)) >> 15;

  //#ifdef DEBUG_PHY
  //    msg("l=%d, phase_offset = %f (%d,%d), freq_offset_est = %d Hz, freq_offset_filt = %d \n",l,phase_offset,omega_cpx->r,omega_cpx->i,freq_offset_est,*freq_offset);
    /*
    for (i=0;i<150;i++)
      msg("i %d : %d,%d <=> %d,%d\n",i,dl_ch[2*i],dl_ch[(2*i)+1],dl_ch_prev[2*i],dl_ch_prev[(2*i)+1]);
    */
    //#endif

  return(0);
}
示例#2
0
void rx_ulsch(LTE_eNB_COMMON *eNB_common_vars,
	      LTE_eNB_ULSCH *eNB_ulsch_vars,
	      LTE_DL_FRAME_PARMS *frame_parms,
	      unsigned int subframe,
	      unsigned char eNB_id,  // this is the effective sector id
	      LTE_eNB_ULSCH_t *ulsch,
	      u8 cooperation_flag) {

  unsigned int l,i;
  int avgs;
  unsigned char log2_maxh,aarx;

 
  int avgs_0,avgs_1;
  unsigned log2_maxh_0,log2_maxh_1;
  

  //  unsigned char harq_pid = ( ulsch->RRCConnRequest_flag== 0) ? subframe2harq_pid_tdd(frame_parms->tdd_config,subframe) : 0;
  unsigned char harq_pid = subframe2harq_pid(frame_parms,subframe);
  unsigned char Qm = get_Qm(ulsch->harq_processes[harq_pid]->mcs);
  unsigned short rx_power_correction;

#ifdef DEBUG_ULSCH
  debug_msg("rx_ulsch: eNB_id %d, harq_pid %d, nb_rb %d first_rb %d, cooperation %d\n",eNB_id,harq_pid,ulsch->harq_processes[harq_pid]->nb_rb,ulsch->harq_processes[harq_pid]->first_rb, cooperation_flag);
#endif //DEBUG_ULSCH

  if ( (frame_parms->ofdm_symbol_size == 128) ||
       (frame_parms->ofdm_symbol_size == 512) )
    rx_power_correction = 2;
  else
    rx_power_correction = 1;

  for (l=0;l<frame_parms->symbols_per_tti-1;l++) {
          
#ifdef DEBUG_ULSCH
    msg("rx_ulsch : symbol %d (first_rb %d,nb_rb %d), rxdataF %p, rxdataF_ext %p\n",l,
	ulsch->harq_processes[harq_pid]->first_rb,
	ulsch->harq_processes[harq_pid]->nb_rb,
	eNB_common_vars->rxdataF[eNB_id],
    	eNB_ulsch_vars->rxdataF_ext[eNB_id]);
#endif //DEBUG_ULSCH

    ulsch_extract_rbs_single(eNB_common_vars->rxdataF[eNB_id],
			     eNB_ulsch_vars->rxdataF_ext[eNB_id],
			     ulsch->harq_processes[harq_pid]->first_rb,
			     ulsch->harq_processes[harq_pid]->nb_rb,
			     l%(frame_parms->symbols_per_tti/2),
			     l/(frame_parms->symbols_per_tti/2),
			     frame_parms);
    
    lte_ul_channel_estimation(eNB_ulsch_vars->drs_ch_estimates[eNB_id],
			      eNB_ulsch_vars->drs_ch_estimates_time[eNB_id],
			      eNB_ulsch_vars->drs_ch_estimates_0[eNB_id],
			      eNB_ulsch_vars->drs_ch_estimates_1[eNB_id],
			      eNB_ulsch_vars->rxdataF_ext[eNB_id],
			      frame_parms,
			      l%(frame_parms->symbols_per_tti/2),
			      l/(frame_parms->symbols_per_tti/2),
			      ulsch->harq_processes[harq_pid]->nb_rb,
			      ulsch->cyclicShift,
			      cooperation_flag);



    ulsch_correct_ext(eNB_ulsch_vars->rxdataF_ext[eNB_id],
		      eNB_ulsch_vars->rxdataF_ext2[eNB_id],
		      l,
		      frame_parms,
		      ulsch->harq_processes[harq_pid]->nb_rb);  
    
    if(cooperation_flag == 2)
      {
	for (i=0;i<frame_parms->nb_antennas_rx;i++){
	  eNB_ulsch_vars->ulsch_power_0[i] = signal_energy_nodc(eNB_ulsch_vars->drs_ch_estimates_0[eNB_id][i],
						ulsch->harq_processes[harq_pid]->nb_rb*12)*rx_power_correction;
	  eNB_ulsch_vars->ulsch_power_1[i] = signal_energy_nodc(eNB_ulsch_vars->drs_ch_estimates_1[eNB_id][i],
						ulsch->harq_processes[harq_pid]->nb_rb*12)*rx_power_correction;
	}
      }
    else
      {
	for (i=0;i<frame_parms->nb_antennas_rx;i++)
	  eNB_ulsch_vars->ulsch_power[i] = signal_energy_nodc(eNB_ulsch_vars->drs_ch_estimates[eNB_id][i],
					      ulsch->harq_processes[harq_pid]->nb_rb*12)*rx_power_correction;
      }
  }


  if(cooperation_flag == 2)
    {
      ulsch_channel_level(eNB_ulsch_vars->drs_ch_estimates_0[eNB_id],
			  frame_parms,
			  avgU_0,
			  ulsch->harq_processes[harq_pid]->nb_rb);
    
      //  msg("[ULSCH] avg_0[0] %d\n",avgU_0[0]);
  

      avgs_0 = 0;
      for (aarx=0;aarx<frame_parms->nb_antennas_rx;aarx++)
	avgs_0 = cmax(avgs_0,avgU_0[(aarx<<1)]);
  
      log2_maxh_0 = 4+(log2_approx(avgs_0)/2);
#ifdef DEBUG_ULSCH
      msg("[ULSCH] log2_maxh_0 = %d (%d,%d)\n",log2_maxh_0,avgU_0[0],avgs_0);
#endif

      ulsch_channel_level(eNB_ulsch_vars->drs_ch_estimates_1[eNB_id],
			  frame_parms,
			  avgU_1,
			  ulsch->harq_processes[harq_pid]->nb_rb);
    
      //  msg("[ULSCH] avg_1[0] %d\n",avgU_1[0]);
  

      avgs_1 = 0;
      for (aarx=0;aarx<frame_parms->nb_antennas_rx;aarx++)
	avgs_1 = cmax(avgs_1,avgU_1[(aarx<<1)]);
  
      log2_maxh_1 = 4+(log2_approx(avgs_1)/2);
#ifdef DEBUG_ULSCH
      msg("[ULSCH] log2_maxh_1 = %d (%d,%d)\n",log2_maxh_1,avgU_1[0],avgs_1);
#endif
    }
  else
    {
      ulsch_channel_level(eNB_ulsch_vars->drs_ch_estimates[eNB_id],
			  frame_parms,
			  avgU,
			  ulsch->harq_processes[harq_pid]->nb_rb);
    
      //  msg("[ULSCH] avg[0] %d\n",avgU[0]);
  

      avgs = 0;
      for (aarx=0;aarx<frame_parms->nb_antennas_rx;aarx++)
	avgs = cmax(avgs,avgU[(aarx<<1)]);
  
      log2_maxh = 2+(log2_approx(avgs)/2);
#ifdef DEBUG_ULSCH
      msg("[ULSCH] log2_maxh = %d (%d,%d)\n",log2_maxh,avgU[0],avgs);
#endif
    }

  for (l=0;l<frame_parms->symbols_per_tti-1;l++) {

    if (((frame_parms->Ncp == 0) && ((l==3) || (l==10)))||   // skip pilots
	((frame_parms->Ncp == 1) && ((l==2) || (l==8)))) {
      l++;
    }    

    if(cooperation_flag == 2)
      {

	ulsch_channel_compensation_alamouti(eNB_ulsch_vars->rxdataF_ext2[eNB_id],
					    eNB_ulsch_vars->drs_ch_estimates_0[eNB_id],
					    eNB_ulsch_vars->drs_ch_estimates_1[eNB_id],
					    eNB_ulsch_vars->ul_ch_mag_0[eNB_id],
					    eNB_ulsch_vars->ul_ch_magb_0[eNB_id],
					    eNB_ulsch_vars->ul_ch_mag_1[eNB_id],
					    eNB_ulsch_vars->ul_ch_magb_1[eNB_id],
					    eNB_ulsch_vars->rxdataF_comp_0[eNB_id],
					    eNB_ulsch_vars->rxdataF_comp_1[eNB_id],
					    frame_parms,
					    l,
					    Qm,
					    ulsch->harq_processes[harq_pid]->nb_rb,
					    log2_maxh_0,
					    log2_maxh_1); // log2_maxh+I0_shift

	ulsch_alamouti(frame_parms,
		       eNB_ulsch_vars->rxdataF_comp[eNB_id],
		       eNB_ulsch_vars->rxdataF_comp_0[eNB_id],
		       eNB_ulsch_vars->rxdataF_comp_1[eNB_id],
		       eNB_ulsch_vars->ul_ch_mag[eNB_id],
		       eNB_ulsch_vars->ul_ch_magb[eNB_id],
		       eNB_ulsch_vars->ul_ch_mag_0[eNB_id],
		       eNB_ulsch_vars->ul_ch_magb_0[eNB_id],
		       eNB_ulsch_vars->ul_ch_mag_1[eNB_id],
		       eNB_ulsch_vars->ul_ch_magb_1[eNB_id],
		       l,
		       ulsch->harq_processes[harq_pid]->nb_rb);
      }
    else
      {
	ulsch_channel_compensation(eNB_ulsch_vars->rxdataF_ext2[eNB_id],
				   eNB_ulsch_vars->drs_ch_estimates[eNB_id],
				   eNB_ulsch_vars->ul_ch_mag[eNB_id],
				   eNB_ulsch_vars->ul_ch_magb[eNB_id],
				   eNB_ulsch_vars->rxdataF_comp[eNB_id],
				   frame_parms,
				   l,
				   Qm,
				   ulsch->harq_processes[harq_pid]->nb_rb,
				   log2_maxh); // log2_maxh+I0_shift
      }
    if (frame_parms->nb_antennas_rx > 1)
      ulsch_detection_mrc(frame_parms,
			  eNB_ulsch_vars->rxdataF_comp[eNB_id],
			  eNB_ulsch_vars->ul_ch_mag[eNB_id],
			  eNB_ulsch_vars->ul_ch_magb[eNB_id],
			  l,
			  ulsch->harq_processes[harq_pid]->nb_rb);
#ifndef OFDMA_ULSCH
    freq_equalization(frame_parms,
		      eNB_ulsch_vars->rxdataF_comp[eNB_id],
		      eNB_ulsch_vars->ul_ch_mag[eNB_id],
		      eNB_ulsch_vars->ul_ch_magb[eNB_id],
		      l,
		      ulsch->harq_processes[harq_pid]->nb_rb*12,
		      Qm);
		      
#endif
  }

#ifndef OFDMA_ULSCH
        
  //#ifdef DEBUG_ULSCH
  // Inverse-Transform equalized outputs
  //  msg("Doing IDFTs\n");
  lte_idft(frame_parms,
	   eNB_ulsch_vars->rxdataF_comp[eNB_id][0],
	   ulsch->harq_processes[harq_pid]->nb_rb*12);
  //  msg("Done\n"); 
  //#endif //DEBUG_ULSCH

#endif

  for (l=0;l<frame_parms->symbols_per_tti-1;l++) {
    
    if (((frame_parms->Ncp == 0) && ((l==3) || (l==10)))||   // skip pilots
	((frame_parms->Ncp == 1) && ((l==2) || (l==8)))) {
      l++;
    }    
    
    switch (Qm) {
    case 2 : 
      ulsch_qpsk_llr(frame_parms,
		     eNB_ulsch_vars->rxdataF_comp[eNB_id],
		     eNB_ulsch_vars->llr,
		     l,
		     ulsch->harq_processes[harq_pid]->nb_rb);
      break;
    case 4 :
      ulsch_16qam_llr(frame_parms,
		      eNB_ulsch_vars->rxdataF_comp[eNB_id],
		      eNB_ulsch_vars->llr,
		      eNB_ulsch_vars->ul_ch_mag[eNB_id],
		      l,ulsch->harq_processes[harq_pid]->nb_rb);
      break;
    case 6 :
      ulsch_64qam_llr(frame_parms,
		      eNB_ulsch_vars->rxdataF_comp[eNB_id],
		      eNB_ulsch_vars->llr,
		      eNB_ulsch_vars->ul_ch_mag[eNB_id],
		      eNB_ulsch_vars->ul_ch_magb[eNB_id],
		      l,ulsch->harq_processes[harq_pid]->nb_rb);
      break;
    default:
#ifdef DEBUG_ULSCH
      msg("ulsch_demodulation.c (rx_ulsch): Unknown Qm!!!!\n");
#endif //DEBUG_ULSCH
      break;
    }
  }

}