slot_fep.c 8.06 KB
Newer Older
ghaddab's avatar
ghaddab committed
1
/*******************************************************************************
2
    OpenAirInterface
ghaddab's avatar
ghaddab committed
3 4 5 6 7 8 9 10 11 12 13 14 15 16
    Copyright(c) 1999 - 2014 Eurecom

    OpenAirInterface is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.


    OpenAirInterface is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
17 18
    along with OpenAirInterface.The full GNU General Public License is
   included in this distribution in the file called "COPYING". If not,
ghaddab's avatar
ghaddab committed
19 20 21 22 23 24
   see <http://www.gnu.org/licenses/>.

  Contact Information
  OpenAirInterface Admin: openair_admin@eurecom.fr
  OpenAirInterface Tech : openair_tech@eurecom.fr
  OpenAirInterface Dev  : openair4g-devel@eurecom.fr
25

ghaddab's avatar
ghaddab committed
26
  Address      : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
ghaddab's avatar
ghaddab committed
27 28

 *******************************************************************************/
29 30 31 32 33 34 35
#include "PHY/defs.h"
#include "MAC_INTERFACE/extern.h"
#include "defs.h"
//#define DEBUG_FEP

#define SOFFSET 0

36

37
int slot_fep(PHY_VARS_UE *phy_vars_ue,
38 39 40
             unsigned char l,
             unsigned char Ns,
             int sample_offset,
41 42
             int no_prefix,
	     int reset_freq_est)
43
{
44 45 46

  LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_ue->lte_frame_parms;
  LTE_UE_COMMON *ue_common_vars   = &phy_vars_ue->lte_ue_common_vars;
47
  uint8_t eNB_id = 0;//ue_common_vars->eNb_id;
48 49 50 51 52 53 54 55 56 57 58
  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;

  void (*dft)(int16_t *,int16_t *, int);
knopp's avatar
knopp committed
59
  int tmp_dft_in[256];  // This is for misalignment issues for 6 and 15 PRBs
60 61 62 63 64

  switch (frame_parms->log2_symbol_size) {
  case 7:
    dft = dft128;
    break;
65

66 67 68
  case 8:
    dft = dft256;
    break;
69

70 71 72
  case 9:
    dft = dft512;
    break;
73

74 75 76
  case 10:
    dft = dft1024;
    break;
77

78 79 80
  case 11:
    dft = dft2048;
    break;
81

82 83 84 85 86 87 88 89
  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);
90
  } else {
91 92 93
    subframe_offset = frame_parms->samples_per_tti * (Ns>>1);
    slot_offset = (frame_parms->samples_per_tti>>1) * (Ns%2);
  }
94

95 96 97 98 99 100 101
  //  subframe_offset_F = frame_parms->ofdm_symbol_size * frame_parms->symbols_per_tti * (Ns>>1);


  if (l<0 || l>=7-frame_parms->Ncp) {
    msg("slot_fep: l must be between 0 and %d\n",7-frame_parms->Ncp);
    return(-1);
  }
102

103 104 105 106 107 108
  if (Ns<0 || Ns>=20) {
    msg("slot_fep: Ns must be between 0 and 19\n");
    return(-1);
  }


109 110

  for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
111 112
    memset(&ue_common_vars->rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],0,frame_parms->ofdm_symbol_size*sizeof(int));

knopp's avatar
knopp committed
113 114 115 116 117
    rx_offset = sample_offset + slot_offset + nb_prefix_samples0 + subframe_offset - SOFFSET;
    // Align with 128 bit
    rx_offset = rx_offset - rx_offset % 4;

#ifdef DEBUG_FEP
118 119 120
    //  if (phy_vars_ue->frame <100)
    msg("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\n", phy_vars_ue->frame_rx,Ns, symbol,
        nb_prefix_samples,nb_prefix_samples0,slot_offset,subframe_offset,sample_offset,rx_offset);
knopp's avatar
knopp committed
121
#endif
122

123
    if (l==0) {
knopp's avatar
knopp committed
124

125
      if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size))
126 127 128
        memcpy((short *)&ue_common_vars->rxdata[aa][frame_length_samples],
               (short *)&ue_common_vars->rxdata[aa][0],
               frame_parms->ofdm_symbol_size*sizeof(int));
129 130

      if ((rx_offset&3)!=0) {  // if input to dft is not 128-bit aligned, issue for size 6 and 15 PRBs
131 132 133 134 135 136 137
        memcpy((void *)tmp_dft_in,
               (void *)&ue_common_vars->rxdata[aa][(rx_offset-nb_prefix_samples0) % frame_length_samples],
               frame_parms->ofdm_symbol_size*sizeof(int));
        dft((int16_t *)tmp_dft_in,
            (int16_t *)&ue_common_vars->rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
      } else { // use dft input from RX buffer directly
        start_meas(&phy_vars_ue->rx_dft_stats);
138

139 140 141 142
        dft((int16_t *)&ue_common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
            (int16_t *)&ue_common_vars->rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
        stop_meas(&phy_vars_ue->rx_dft_stats);

143
      }
144
    } else {
knopp's avatar
knopp committed
145
      rx_offset += (frame_parms->ofdm_symbol_size+nb_prefix_samples) +
146
                   (frame_parms->ofdm_symbol_size+nb_prefix_samples)*(l-1);
147

knopp's avatar
knopp committed
148
#ifdef DEBUG_FEP
149 150 151
      //  if (phy_vars_ue->frame <100)
      msg("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\n", phy_vars_ue->frame_rx,Ns, symbol,
          nb_prefix_samples,nb_prefix_samples0,slot_offset,subframe_offset,sample_offset,rx_offset);
knopp's avatar
knopp committed
152
#endif
153

154
      if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size))
155 156 157 158
        memcpy((void *)&ue_common_vars->rxdata[aa][frame_length_samples],
               (void *)&ue_common_vars->rxdata[aa][0],
               frame_parms->ofdm_symbol_size*sizeof(int));

knopp's avatar
knopp committed
159
      start_meas(&phy_vars_ue->rx_dft_stats);
160

knopp's avatar
knopp committed
161
      if ((rx_offset&3)!=0) {  // if input to dft is not 128-bit aligned, issue for size 6 and 15 PRBs
162 163 164 165 166 167
        memcpy((void *)tmp_dft_in,
               (void *)&ue_common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
               frame_parms->ofdm_symbol_size*sizeof(int));
        dft((int16_t *)tmp_dft_in,
            (int16_t *)&ue_common_vars->rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
      } else { // use dft input from RX buffer directly
168

169 170
        dft((int16_t *)&ue_common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
            (int16_t *)&ue_common_vars->rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
171
      }
172

knopp's avatar
knopp committed
173 174 175
      stop_meas(&phy_vars_ue->rx_dft_stats);


176
    }
knopp's avatar
knopp committed
177

178
  }
knopp's avatar
knopp committed
179

knopp's avatar
knopp committed
180
  if (phy_vars_ue->perfect_ce == 0) {
181 182
    if ((l==0) || (l==(4-frame_parms->Ncp))) {
      for (aa=0; aa<frame_parms->nb_antennas_tx_eNB; aa++) {
183 184

#ifdef DEBUG_FEP
185
        msg("Channel estimation eNB %d, aatx %d, slot %d, symbol %d\n",eNB_id,aa,Ns,l);
186
#endif
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
        start_meas(&phy_vars_ue->dlsch_channel_estimation_stats);
        lte_dl_channel_estimation(phy_vars_ue,eNB_id,0,
                                  Ns,
                                  aa,
                                  l,
                                  symbol);
        stop_meas(&phy_vars_ue->dlsch_channel_estimation_stats);

        for (i=0; i<phy_vars_ue->PHY_measurements.n_adj_cells; i++) {
          lte_dl_channel_estimation(phy_vars_ue,eNB_id,i+1,
                                    Ns,
                                    aa,
                                    l,
                                    symbol);
        }
202 203 204 205
      }


      // do frequency offset estimation here!
206
      // use channel estimates from current symbol (=ch_t) and last symbol (ch_{t-1})
207 208
#ifdef DEBUG_FEP
      msg("Frequency offset estimation\n");
209 210
#endif

knopp's avatar
knopp committed
211
      if (l==(4-frame_parms->Ncp)) {
212 213 214 215
        start_meas(&phy_vars_ue->dlsch_freq_offset_estimation_stats);
        lte_est_freq_offset(ue_common_vars->dl_ch_estimates[0],
                            frame_parms,
                            l,
216 217
                            &ue_common_vars->freq_offset,
			    reset_freq_est);
218
        stop_meas(&phy_vars_ue->dlsch_freq_offset_estimation_stats);
219 220

      }
221
    }
222
  }
223

224 225 226 227 228
#ifdef DEBUG_FEP
  msg("slot_fep: done\n");
#endif
  return(0);
}