/******************************************************************************* 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