lte_dl_channel_estimation_emos.c 4.33 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
Cedric Roux's avatar
Cedric Roux committed
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
#include <string.h>
#include "defs.h"
#include "PHY/defs.h"
#include "SCHED/phy_procedures_emos.h"

// TODO: make channel estimation possible for multiple sectors (Gold sequences for pilots)

//#define DEBUG_CH
int lte_dl_channel_estimation_emos(int dl_ch_estimates_emos[NB_ANTENNAS_RX*NB_ANTENNAS_TX][N_RB_DL_EMOS*N_PILOTS_PER_RB*N_SLOTS_EMOS],
31
32
33
34
35
36
37
38
                                   int **rxdataF,
                                   LTE_DL_FRAME_PARMS *frame_parms,
                                   unsigned char Ns,
                                   unsigned char p,
                                   unsigned char l,
                                   unsigned char sector)
{

39
40
41
42
43
44
45
46
  int pilot[2][200] __attribute__((aligned(16)));
  unsigned char nu,aarx;
  unsigned short k;
  unsigned int rb,pilot_cnt;
  short ch[2],*pil,*rxF,*dl_ch,*dl_ch_prev; //*f,*f2,*fl,*f2l2,*fr,*f2r2;
  int ch_offset,symbol_offset;
  unsigned int n;
  int i;
47

48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
  unsigned char symbol = l+((7-frame_parms->Ncp)*(Ns&1)); ///symbol within sub-frame

  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_emos: p %d, l %d -> ERROR\n",p,l);
    return(-1);
  }

63
  if (sector > 2) {
64
65
66
67
68
69
70
71
    msg("lte_dl_channel_estimation_emos: sector must be 0,1, or 2\n");
    return(-1);
  }

  switch (Ns) {
  case 0:
    ch_offset = ((l==0)?0:1)*2*frame_parms->N_RB_DL;
    break;
72

73
74
75
  case 1:
    ch_offset = ((l==0)?2:3)*2*frame_parms->N_RB_DL;
    break;
76

77
78
79
  case 12:
    ch_offset = ((l==0)?4:5)*2*frame_parms->N_RB_DL;
    break;
80

81
82
83
  case 13:
    ch_offset = ((l==0)?6:7)*2*frame_parms->N_RB_DL;
    break;
84

85
86
87
88
89
90
91
92
93
94
  default:
    msg("lte_dl_channel_estimation_emos: Ns must be  0, 1, 12, or 13\n");
    return(-1);
    break;

  }

  symbol_offset = symbol*frame_parms->ofdm_symbol_size; // offset within rxdataF

  k = nu + sector;
95

96
97
  if (k > 6)
    k -=6;
98

99
100
101
#ifdef DEBUG_CH
  printf("Channel Estimation : ch_offset %d, OFDM size %d, Ncp=%d, l=%d, Ns=%d, k=%d, symbol=%d\n",ch_offset,frame_parms->ofdm_symbol_size,frame_parms->Ncp,l,Ns,k,symbol);
#endif
102

103
104
  // generate pilot
  lte_dl_cell_spec_rx(&pilot[p][0],
105
106
107
108
109
110
111
112
                      frame_parms,
                      Ns,
                      (l==0)?0:1,
                      p);


  for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {

113
    pil   = (short *)&pilot[p][0];
114
    rxF   = (short *)&rxdataF[aarx][((symbol_offset+k+frame_parms->first_carrier_offset)<<1)];
115
116
    dl_ch = (short *)&dl_ch_estimates_emos[(p<<1)+aarx][ch_offset];
    memset(dl_ch,0,frame_parms->N_RB_DL);
117
118

    for (pilot_cnt=0; pilot_cnt<frame_parms->N_RB_DL; pilot_cnt++) {
119
120
121

      dl_ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15);
      dl_ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15);
122

123
124
125
      pil+=2;    // Re Im
      rxF+=24;   // remember replicated format (Re0 Im0 Re0 Im0) !!!
      dl_ch+=2;
126

127
    }
128

129
130
    // printf("Second half\n");
    // Second half of RBs
131
132
133
134
135
    rxF   = (short *)&rxdataF[aarx][((symbol_offset+1+k)<<1)];

    for (pilot_cnt=0; pilot_cnt<frame_parms->N_RB_DL; pilot_cnt++) {


136
137
      dl_ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15);
      dl_ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15);
138

139
140
141
      pil+=2;
      rxF+=24;
      dl_ch+=2;
142

143
144
145
146
    }

  }

147
  return(0);
148
149
}