drs_modulation.c 6.74 KB
Newer Older
1 2 3 4 5
/*
 * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The OpenAirInterface Software Alliance licenses this file to You under
6
 * the OAI Public License, Version 1.1  (the "License"); you may not use this file
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
 * except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.openairinterface.org/?page_id=698
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *-------------------------------------------------------------------------------
 * For more information about the OpenAirInterface (OAI) Software Alliance:
 *      contact@openairinterface.org
 */

22 23 24 25 26 27 28 29 30 31
/*! \file PHY/LTE_TRANSPORT/drs_modulation.c
* \brief Top-level routines for generating the Demodulation Reference Signals from 36-211, V8.6 2009-03
* \author R. Knopp, F. Kaltenberger, A. Bhamri
* \date 2011
* \version 0.1
* \company Eurecom
* \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr,ankit.bhamri@eurecom.fr
* \note
* \warning
*/
32 33
#include "PHY/defs_UE.h"
#include "PHY/phy_extern_ue.h"
34
#include "PHY/sse_intrin.h"
35 36
#include "transport_proto_ue.h"

37 38
//#define DEBUG_DRS

39
int generate_drs_pusch(PHY_VARS_UE *ue,
40
		       UE_rxtx_proc_t *proc,
41 42
		       LTE_DL_FRAME_PARMS *frame_parms,
		       int32_t **txdataF,
43 44 45 46 47 48 49
                       uint8_t eNB_id,
                       short amp,
                       unsigned int subframe,
                       unsigned int first_rb,
                       unsigned int nb_rb,
                       uint8_t ant)
{
50

51 52
  uint16_t k,l,Msc_RS,Msc_RS_idx,rb,drs_offset;
  uint16_t * Msc_idx_ptr;
53 54
  int subframe_offset,re_offset,symbol_offset;

55 56
  //uint32_t phase_shift; // phase shift for cyclic delay in DM RS
  //uint8_t alpha_ind;
57

58 59
  int16_t alpha_re[12] = {32767, 28377, 16383,     0,-16384,  -28378,-32768,-28378,-16384,    -1, 16383, 28377};
  int16_t alpha_im[12] = {0,     16383, 28377, 32767, 28377,   16383,     0,-16384,-28378,-32768,-28378,-16384};
60

61 62 63
  uint8_t cyclic_shift,cyclic_shift0=0,cyclic_shift1=0;
  LTE_DL_FRAME_PARMS *fp = (ue==NULL) ? frame_parms : &ue->frame_parms;
  int32_t *txF = (ue==NULL) ? txdataF[ant] : ue->common_vars.txdataF[ant];
64
  uint32_t u,v,alpha_ind;
65
  uint32_t u0=0,u1=0,v0=0,v1=0;
66
  int32_t ref_re,ref_im;
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
  uint8_t harq_pid = (proc == NULL) ? 0: subframe2harq_pid(fp,proc->frame_tx,subframe);

  if (ue!=NULL) {
    cyclic_shift0 = (fp->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift +
		     ue->ulsch[eNB_id]->harq_processes[harq_pid]->n_DMRS2 +
		     fp->pusch_config_common.ul_ReferenceSignalsPUSCH.nPRS[subframe<<1]+
		     ((ue->ulsch[0]->cooperation_flag==2)?10:0)+
		     ant*6) % 12;
    //  printf("PUSCH.cyclicShift %d, n_DMRS2 %d, nPRS %d\n",frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift,ue->ulsch[eNB_id]->n_DMRS2,ue->lte_frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.nPRS[subframe<<1]);
    cyclic_shift1 = (fp->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift +
		     ue->ulsch[eNB_id]->harq_processes[harq_pid]->n_DMRS2 +
		     fp->pusch_config_common.ul_ReferenceSignalsPUSCH.nPRS[(subframe<<1)+1]+
		     ((ue->ulsch[0]->cooperation_flag==2)?10:0)+
		     ant*6) % 12;
    u0=fp->pusch_config_common.ul_ReferenceSignalsPUSCH.grouphop[subframe<<1];
    u1=fp->pusch_config_common.ul_ReferenceSignalsPUSCH.grouphop[1+(subframe<<1)];
    v0=fp->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[subframe<<1];
    v1=fp->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[1+(subframe<<1)];
  }
86

87
  
88 89
  //       cyclic_shift0 = 0;
  //        cyclic_shift1 = 0;
90
  Msc_RS = 12*nb_rb;
91

92
  Msc_idx_ptr = (uint16_t*) bsearch(&Msc_RS, dftsizes, 34, sizeof(uint16_t), compareints);
93

94 95 96
  if (Msc_idx_ptr)
    Msc_RS_idx = Msc_idx_ptr - dftsizes;
  else {
97
    LOG_I(PHY,"generate_drs_pusch: index for Msc_RS=%d not found\n",Msc_RS);
98 99
    return(-1);
  }
100

101
  for (l = (3 - fp->Ncp),u=u0,v=v0,cyclic_shift=cyclic_shift0;
102
       l<fp->symbols_per_tti;
103
       l += (7 - fp->Ncp),u=u1,v=v1,cyclic_shift=cyclic_shift1) {
104

Cedric Roux's avatar
Cedric Roux committed
105
    drs_offset = 0;
106 107 108
#ifdef DEBUG_DRS
    printf("drs_modulation: Msc_RS = %d, Msc_RS_idx = %d, u=%d,v=%d\n",Msc_RS, Msc_RS_idx,u,v);
#endif
109 110


111
    re_offset = fp->first_carrier_offset;
112
    subframe_offset = subframe*fp->symbols_per_tti*fp->ofdm_symbol_size;
113
    symbol_offset = subframe_offset + fp->ofdm_symbol_size*l;
114

115
#ifdef DEBUG_DRS
116
    printf("generate_drs_pusch: symbol_offset %d, subframe offset %d, cyclic shift %d\n",symbol_offset,subframe_offset,cyclic_shift);
117 118
#endif
    alpha_ind = 0;
119

120
    for (rb=0; rb<fp->N_RB_UL; rb++) {
121 122 123

      if ((rb >= first_rb) && (rb<(first_rb+nb_rb))) {

124
#ifdef DEBUG_DRS
125
        printf("generate_drs_pusch: doing RB %d, re_offset=%d, drs_offset=%d,cyclic shift %d\n",rb,re_offset,drs_offset,cyclic_shift);
126 127
#endif

128 129 130 131
        for (k=0; k<12; k++) {
          ref_re = (int32_t) ul_ref_sigs[u][v][Msc_RS_idx][drs_offset<<1];
          ref_im = (int32_t) ul_ref_sigs[u][v][Msc_RS_idx][(drs_offset<<1)+1];

132
          ((int16_t*) txF)[2*(symbol_offset + re_offset)]   = (int16_t) (((ref_re*alpha_re[alpha_ind]) -
133
              (ref_im*alpha_im[alpha_ind]))>>15);
134
          ((int16_t*) txF)[2*(symbol_offset + re_offset)+1] = (int16_t) (((ref_re*alpha_im[alpha_ind]) +
135
              (ref_im*alpha_re[alpha_ind]))>>15);
136 137
          ((short*) txF)[2*(symbol_offset + re_offset)]   = (short) ((((short*) txF)[2*(symbol_offset + re_offset)]*(int32_t)amp)>>15);
          ((short*) txF)[2*(symbol_offset + re_offset)+1] = (short) ((((short*) txF)[2*(symbol_offset + re_offset)+1]*(int32_t)amp)>>15);
138 139 140 141 142 143 144


          alpha_ind = (alpha_ind + cyclic_shift);

          if (alpha_ind > 11)
            alpha_ind-=12;

145
#ifdef DEBUG_DRS
146
          printf("symbol_offset %d, alpha_ind %d , re_offset %d : (%d,%d)\n",
147 148 149
              symbol_offset,
              alpha_ind,
              re_offset,
150 151
              ((short*) txF)[2*(symbol_offset + re_offset)],
              ((short*) txF)[2*(symbol_offset + re_offset)+1]);
152

153
#endif  // DEBUG_DRS
154 155 156
          re_offset++;
          drs_offset++;

157
          if (re_offset >= fp->ofdm_symbol_size)
158 159 160 161 162 163 164 165
            re_offset = 0;
        }

      } else {
        re_offset+=12; // go to next RB

        // check if we crossed the symbol boundary and skip DC

166 167
        if (re_offset >= fp->ofdm_symbol_size) {
          if (fp->N_RB_DL&1)  // odd number of RBs
168 169 170 171 172
            re_offset=6;
          else                         // even number of RBs (doesn't straddle DC)
            re_offset=0;
        }

173

174 175 176
      }
    }
  }
177

178 179 180
  return(0);
}