335 lines
9.1 KiB
C
335 lines
9.1 KiB
C
/*******************************************************************************
|
|
OpenAirInterface
|
|
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
|
|
along with OpenAirInterface.The full GNU General Public License is
|
|
included in this distribution in the file called "COPYING". If not,
|
|
see <http://www.gnu.org/licenses/>.
|
|
|
|
Contact Information
|
|
OpenAirInterface Admin: openair_admin@eurecom.fr
|
|
OpenAirInterface Tech : openair_tech@eurecom.fr
|
|
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
|
|
|
|
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
|
|
|
*******************************************************************************/
|
|
#ifdef USER_MODE
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#endif
|
|
|
|
#include "defs.h"
|
|
#include "PHY/defs.h"
|
|
|
|
//extern unsigned int lte_gold_table[3][20][2][14];
|
|
//#define DEBUG_DL_CELL_SPEC
|
|
|
|
|
|
|
|
//Calibration
|
|
int lte_dl_cell_spec_SS(PHY_VARS_eNB *phy_vars_eNB,
|
|
int32_t *output,
|
|
short amp,
|
|
unsigned char Ns,
|
|
unsigned char l,//nb of sym per slot
|
|
unsigned char p) //nb of antennas
|
|
{
|
|
|
|
unsigned char nu,mprime,mprime_dword,mprime_qpsk_symb,m;
|
|
unsigned short k,a;
|
|
int32_t qpsk[4];
|
|
|
|
a = (amp*ONE_OVER_SQRT2_Q15)>>15;
|
|
((short *)&qpsk[0])[0] = a;
|
|
((short *)&qpsk[0])[1] = a;
|
|
((short *)&qpsk[1])[0] = -a;
|
|
((short *)&qpsk[1])[1] = a;
|
|
((short *)&qpsk[2])[0] = a;
|
|
((short *)&qpsk[2])[1] = -a;
|
|
((short *)&qpsk[3])[0] = -a;
|
|
((short *)&qpsk[3])[1] = -a;
|
|
|
|
|
|
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 {
|
|
printf("lte_dl_cell_spec: p %d, l %d -> ERROR\n",p,l);
|
|
return(-1);
|
|
}
|
|
|
|
mprime = 110 - phy_vars_eNB->lte_frame_parms.N_RB_DL;
|
|
|
|
k = (nu + phy_vars_eNB->lte_frame_parms.nushift);
|
|
|
|
if (k > 6)//b
|
|
k -=6;//b
|
|
|
|
k+=phy_vars_eNB->lte_frame_parms.first_carrier_offset;
|
|
|
|
for (m=0; m<phy_vars_eNB->lte_frame_parms.N_RB_DL<<1; m++) { // loop over pilots in one slot/symbol, 2*N_RB_DL pilots
|
|
|
|
mprime_dword = mprime>>4;
|
|
mprime_qpsk_symb = mprime&0xf;
|
|
|
|
// this is r_mprime from 3GPP 36-211 6.10.1.2
|
|
output[k] = qpsk[(phy_vars_eNB->lte_gold_table[Ns][l][mprime_dword]>>(2*mprime_qpsk_symb))&3];
|
|
//output[k] = (lte_gold_table[eNB_offset][Ns][l][mprime_dword]>>(2*mprime_qpsk_symb))&3;
|
|
#ifdef DEBUG_DL_CELL_SPEC
|
|
printf("Ns %d, l %d, m %d,mprime_dword %d, mprime_qpsk_symbol %d\n",
|
|
Ns,l,m,mprime_dword,mprime_qpsk_symb);
|
|
printf("index = %d (k %d)\n",(phy_vars_eNB->lte_gold_table[Ns][l][mprime_dword]>>(2*mprime_qpsk_symb))&3,k);
|
|
#endif
|
|
|
|
mprime++;
|
|
#ifdef DEBUG_DL_CELL_SPEC
|
|
|
|
if (m<4)
|
|
printf("Ns %d, l %d output[%d] = (%d,%d)\n",Ns,l,k,((short *)&output[k])[0],((short *)&output[k])[1]);
|
|
|
|
#endif
|
|
k+=6;//b
|
|
|
|
if (k >= phy_vars_eNB->lte_frame_parms.ofdm_symbol_size) {
|
|
k++; // skip DC carrier
|
|
k-=phy_vars_eNB->lte_frame_parms.ofdm_symbol_size;
|
|
}
|
|
|
|
// printf("** k %d\n",k);
|
|
}
|
|
|
|
return(0);
|
|
}
|
|
|
|
|
|
int lte_dl_cell_spec(PHY_VARS_eNB *phy_vars_eNB,
|
|
int32_t *output,
|
|
short amp,
|
|
unsigned char Ns,
|
|
unsigned char l,
|
|
unsigned char p)
|
|
{
|
|
|
|
unsigned char nu,mprime,mprime_dword,mprime_qpsk_symb,m;
|
|
unsigned short k,a;
|
|
int32_t qpsk[4];
|
|
|
|
a = (amp*ONE_OVER_SQRT2_Q15)>>15;
|
|
((short *)&qpsk[0])[0] = a;
|
|
((short *)&qpsk[0])[1] = a;
|
|
((short *)&qpsk[1])[0] = -a;
|
|
((short *)&qpsk[1])[1] = a;
|
|
((short *)&qpsk[2])[0] = a;
|
|
((short *)&qpsk[2])[1] = -a;
|
|
((short *)&qpsk[3])[0] = -a;
|
|
((short *)&qpsk[3])[1] = -a;
|
|
|
|
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 {
|
|
printf("lte_dl_cell_spec: p %d, l %d -> ERROR\n",p,l);
|
|
return(-1);
|
|
}
|
|
|
|
mprime = 110 - phy_vars_eNB->lte_frame_parms.N_RB_DL;
|
|
|
|
k = (nu + phy_vars_eNB->lte_frame_parms.nushift);
|
|
|
|
if (k > 5)
|
|
k -=6;
|
|
|
|
k+=phy_vars_eNB->lte_frame_parms.first_carrier_offset;
|
|
|
|
DevAssert( Ns < 20 );
|
|
DevAssert( l < 2 );
|
|
DevAssert( mprime>>4 < 14 );
|
|
|
|
for (m=0; m<phy_vars_eNB->lte_frame_parms.N_RB_DL<<1; m++) {
|
|
|
|
mprime_dword = mprime>>4;
|
|
mprime_qpsk_symb = mprime&0xf;
|
|
|
|
// this is r_mprime from 3GPP 36-211 6.10.1.2
|
|
output[k] = qpsk[(phy_vars_eNB->lte_gold_table[Ns][l][mprime_dword]>>(2*mprime_qpsk_symb))&3];
|
|
//output[k] = (lte_gold_table[eNB_offset][Ns][l][mprime_dword]>>(2*mprime_qpsk_symb))&3;
|
|
#ifdef DEBUG_DL_CELL_SPEC
|
|
printf("Ns %d, l %d, m %d,mprime_dword %d, mprime_qpsk_symbol %d\n",
|
|
Ns,l,m,mprime_dword,mprime_qpsk_symb);
|
|
printf("index = %d (k %d)\n",(phy_vars_eNB->lte_gold_table[Ns][l][mprime_dword]>>(2*mprime_qpsk_symb))&3,k);
|
|
#endif
|
|
|
|
mprime++;
|
|
#ifdef DEBUG_DL_CELL_SPEC
|
|
|
|
if (m<4)
|
|
printf("Ns %d, l %d output[%d] = (%d,%d)\n",Ns,l,k,((short *)&output[k])[0],((short *)&output[k])[1]);
|
|
|
|
#endif
|
|
k+=6;
|
|
|
|
if (k >= phy_vars_eNB->lte_frame_parms.ofdm_symbol_size) {
|
|
k++; // skip DC carrier
|
|
k-=phy_vars_eNB->lte_frame_parms.ofdm_symbol_size;
|
|
}
|
|
|
|
// printf("** k %d\n",k);
|
|
}
|
|
|
|
return(0);
|
|
}
|
|
|
|
int lte_dl_cell_spec_rx(PHY_VARS_UE *phy_vars_ue,
|
|
uint8_t eNB_offset,
|
|
int *output,
|
|
unsigned char Ns,
|
|
unsigned char l,
|
|
unsigned char p)
|
|
{
|
|
|
|
|
|
unsigned char mprime,mprime_dword,mprime_qpsk_symb,m;
|
|
unsigned short k=0;
|
|
unsigned int qpsk[4];
|
|
short pamp;
|
|
|
|
// Compute the correct pilot amplitude, sqrt_rho_b = Q3.13
|
|
pamp = ONE_OVER_SQRT2_Q15;
|
|
|
|
// This includes complex conjugate for channel estimation
|
|
|
|
((short *)&qpsk[0])[0] = pamp;
|
|
((short *)&qpsk[0])[1] = -pamp;
|
|
((short *)&qpsk[1])[0] = -pamp;
|
|
((short *)&qpsk[1])[1] = -pamp;
|
|
((short *)&qpsk[2])[0] = pamp;
|
|
((short *)&qpsk[2])[1] = pamp;
|
|
((short *)&qpsk[3])[0] = -pamp;
|
|
((short *)&qpsk[3])[1] = pamp;
|
|
|
|
mprime = 110 - phy_vars_ue->lte_frame_parms.N_RB_DL;
|
|
|
|
for (m=0; m<phy_vars_ue->lte_frame_parms.N_RB_DL<<1; m++) {
|
|
|
|
mprime_dword = mprime>>4;
|
|
mprime_qpsk_symb = mprime&0xf;
|
|
|
|
// this is r_mprime from 3GPP 36-211 6.10.1.2
|
|
output[k] = qpsk[(phy_vars_ue->lte_gold_table[eNB_offset][Ns][l][mprime_dword]>>(2*mprime_qpsk_symb))&3];
|
|
#ifdef DEBUG_DL_CELL_SPEC
|
|
printf("Ns %d, l %d, m %d,mprime_dword %d, mprime_qpsk_symbol %d\n",
|
|
Ns,l,m,mprime_dword,mprime_qpsk_symb);
|
|
printf("index = %d (k %d)\n",(phy_vars_ue->lte_gold_table[eNB_offset][Ns][l][mprime_dword]>>(2*mprime_qpsk_symb))&3,k);
|
|
#endif
|
|
|
|
mprime++;
|
|
#ifdef DEBUG_DL_CELL_SPEC
|
|
|
|
if (m<4)
|
|
printf("Ns %d l %d output[%d] = (%d,%d)\n",Ns,l,k,((short *)&output[k])[0],((short *)&output[k])[1]);
|
|
|
|
#endif
|
|
k++;
|
|
// printf("** k %d\n",k);
|
|
}
|
|
|
|
return(0);
|
|
}
|
|
|
|
|
|
#ifdef LTE_DL_CELL_SPEC_MAIN
|
|
|
|
|
|
|
|
//extern int write_output(const char *,const char *,void *,int,int,char);
|
|
// flag change eren
|
|
extern int write_output(const char *,const char *,void *,int,int,char);
|
|
main()
|
|
{
|
|
|
|
unsigned short Nid_cell=0;
|
|
unsigned int Ncp = 0;
|
|
int output00[1024];
|
|
int output01[1024];
|
|
int output10[1024];
|
|
int output11[1024];
|
|
|
|
memset(output00,0,1024*sizeof(int));
|
|
memset(output01,0,1024*sizeof(int));
|
|
memset(output10,0,1024*sizeof(int));
|
|
memset(output11,0,1024*sizeof(int));
|
|
|
|
lte_gold(Nid_cell,Ncp);
|
|
|
|
lte_dl_cell_spec(output00,
|
|
ONE_OVER_SQRT2_Q15,
|
|
50,
|
|
Nid_cell,
|
|
Ncp,
|
|
0,
|
|
0,
|
|
0,
|
|
0);
|
|
|
|
lte_dl_cell_spec(output10,
|
|
ONE_OVER_SQRT2_Q15,
|
|
50,
|
|
Nid_cell,
|
|
Ncp,
|
|
0,
|
|
1,
|
|
0,
|
|
0);
|
|
|
|
lte_dl_cell_spec(output01,
|
|
ONE_OVER_SQRT2_Q15,
|
|
50,
|
|
Nid_cell,
|
|
Ncp,
|
|
0,
|
|
0,
|
|
1,
|
|
0);
|
|
|
|
lte_dl_cell_spec(output11,
|
|
ONE_OVER_SQRT2_Q15,
|
|
50,
|
|
Nid_cell,
|
|
Ncp,
|
|
0,
|
|
1,
|
|
1,
|
|
0);
|
|
|
|
|
|
write_output("dl_cell_spec00.m","dl_cs00",output00,1024,1,1);
|
|
write_output("dl_cell_spec01.m","dl_cs01",output01,1024,1,1);
|
|
write_output("dl_cell_spec10.m","dl_cs10",output10,1024,1,1);
|
|
write_output("dl_cell_spec11.m","dl_cs11",output11,1024,1,1);
|
|
}
|
|
|
|
#endif
|