Addition of phich_common.c
Merge branch 'develop-uedirectorysplit' into nr_initialsync
This commit is contained in:
@@ -0,0 +1,383 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*! \file PHY/LTE_TRANSPORT/phich_common.c
|
||||||
|
* \brief Top-level routines for generating and decoding the PHICH/HI physical/transport channel V8.6 2009-03
|
||||||
|
* \author R. Knopp
|
||||||
|
* \date 2011
|
||||||
|
* \version 0.1
|
||||||
|
* \company Eurecom
|
||||||
|
* \email: knopp@eurecom.fr
|
||||||
|
* \note
|
||||||
|
* \warning
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "PHY/defs_eNB.h"
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t get_mi(LTE_DL_FRAME_PARMS *frame_parms,uint8_t subframe)
|
||||||
|
{
|
||||||
|
|
||||||
|
// for FDD
|
||||||
|
if (frame_parms->frame_type == FDD)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
// for TDD
|
||||||
|
switch (frame_parms->tdd_config) {
|
||||||
|
|
||||||
|
case 0:
|
||||||
|
if ((subframe==0) || (subframe==5))
|
||||||
|
return(2);
|
||||||
|
else return(1);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
if ((subframe==0) || (subframe==5))
|
||||||
|
return(0);
|
||||||
|
else return(1);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
if ((subframe==3) || (subframe==8))
|
||||||
|
return(1);
|
||||||
|
else return(0);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
if ((subframe==0) || (subframe==8) || (subframe==9))
|
||||||
|
return(1);
|
||||||
|
else return(0);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
if ((subframe==8) || (subframe==9))
|
||||||
|
return(1);
|
||||||
|
else return(0);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 5:
|
||||||
|
if (subframe==8)
|
||||||
|
return(1);
|
||||||
|
else return(0);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 6:
|
||||||
|
return(1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char subframe2_ul_harq(LTE_DL_FRAME_PARMS *frame_parms,unsigned char subframe)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (frame_parms->frame_type == FDD)
|
||||||
|
return(subframe&7);
|
||||||
|
|
||||||
|
switch (frame_parms->tdd_config) {
|
||||||
|
case 3:
|
||||||
|
if ( (subframe == 8) || (subframe == 9) ) {
|
||||||
|
return(subframe-8);
|
||||||
|
} else if (subframe==0)
|
||||||
|
return(2);
|
||||||
|
else {
|
||||||
|
LOG_E(PHY,"phich.c: subframe2_ul_harq, illegal subframe %d for tdd_config %d\n",
|
||||||
|
subframe,frame_parms->tdd_config);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
if ( (subframe == 8) || (subframe == 9) ) {
|
||||||
|
return(subframe-8);
|
||||||
|
} else {
|
||||||
|
LOG_E(PHY,"phich.c: subframe2_ul_harq, illegal subframe %d for tdd_config %d\n",
|
||||||
|
subframe,frame_parms->tdd_config);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int phich_frame2_pusch_frame(LTE_DL_FRAME_PARMS *frame_parms, int frame, int subframe)
|
||||||
|
{
|
||||||
|
int pusch_frame;
|
||||||
|
|
||||||
|
if (frame_parms->frame_type == FDD) {
|
||||||
|
pusch_frame = subframe<4 ? frame + 1024 - 1 : frame;
|
||||||
|
} else {
|
||||||
|
// Note this is not true, but it doesn't matter, the frame number is irrelevant for TDD!
|
||||||
|
pusch_frame = (frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
//LOG_D(PHY, "frame %d subframe %d: PUSCH frame = %d\n", frame, subframe, pusch_frame);
|
||||||
|
return pusch_frame % 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t phich_subframe2_pusch_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint8_t subframe)
|
||||||
|
{
|
||||||
|
uint8_t pusch_subframe = 255;
|
||||||
|
|
||||||
|
if (frame_parms->frame_type == FDD)
|
||||||
|
return subframe < 4 ? subframe + 6 : subframe - 4;
|
||||||
|
|
||||||
|
switch (frame_parms->tdd_config) {
|
||||||
|
case 0:
|
||||||
|
if (subframe == 0)
|
||||||
|
pusch_subframe = (3);
|
||||||
|
else if (subframe == 5) {
|
||||||
|
pusch_subframe = (8);
|
||||||
|
} else if (subframe == 6)
|
||||||
|
pusch_subframe = (2);
|
||||||
|
else if (subframe == 1)
|
||||||
|
pusch_subframe = (7);
|
||||||
|
else {
|
||||||
|
AssertFatal(1==0,"phich.c: phich_subframe2_pusch_subframe, illegal subframe %d for tdd_config %d\n",
|
||||||
|
subframe,frame_parms->tdd_config);
|
||||||
|
pusch_subframe = (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
if (subframe == 6)
|
||||||
|
pusch_subframe = (2);
|
||||||
|
else if (subframe == 9)
|
||||||
|
pusch_subframe = (3);
|
||||||
|
else if (subframe == 1)
|
||||||
|
pusch_subframe = (7);
|
||||||
|
else if (subframe == 4)
|
||||||
|
pusch_subframe = (8);
|
||||||
|
else {
|
||||||
|
AssertFatal(1==0,"phich.c: phich_subframe2_pusch_subframe, illegal subframe %d for tdd_config %d\n",
|
||||||
|
subframe,frame_parms->tdd_config);
|
||||||
|
pusch_subframe = (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
if (subframe == 8)
|
||||||
|
pusch_subframe = (2);
|
||||||
|
else if (subframe == 3)
|
||||||
|
pusch_subframe = (7);
|
||||||
|
else {
|
||||||
|
AssertFatal(1==0,"phich.c: phich_subframe2_pusch_subframe, illegal subframe %d for tdd_config %d\n",
|
||||||
|
subframe,frame_parms->tdd_config);
|
||||||
|
pusch_subframe = (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
if ( (subframe == 8) || (subframe == 9) ) {
|
||||||
|
pusch_subframe = (subframe-6);
|
||||||
|
} else if (subframe==0)
|
||||||
|
pusch_subframe = (4);
|
||||||
|
else {
|
||||||
|
AssertFatal(1==0,"phich.c: phich_subframe2_pusch_subframe, illegal subframe %d for tdd_config %d\n",
|
||||||
|
subframe,frame_parms->tdd_config);
|
||||||
|
pusch_subframe = (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
if ( (subframe == 8) || (subframe == 9) ) {
|
||||||
|
pusch_subframe = (subframe-6);
|
||||||
|
} else {
|
||||||
|
AssertFatal(1==0,"phich.c: phich_subframe2_pusch_subframe, illegal subframe %d for tdd_config %d\n",
|
||||||
|
subframe,frame_parms->tdd_config);
|
||||||
|
pusch_subframe = (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 5:
|
||||||
|
if (subframe == 8) {
|
||||||
|
pusch_subframe = (2);
|
||||||
|
} else {
|
||||||
|
AssertFatal(1==0,"phich.c: phich_subframe2_pusch_subframe, illegal subframe %d for tdd_config %d\n",
|
||||||
|
subframe,frame_parms->tdd_config);
|
||||||
|
pusch_subframe = (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 6:
|
||||||
|
if (subframe == 6) {
|
||||||
|
pusch_subframe = (2);
|
||||||
|
} else if (subframe == 9) {
|
||||||
|
pusch_subframe = (3);
|
||||||
|
} else if (subframe == 0) {
|
||||||
|
pusch_subframe = (4);
|
||||||
|
} else if (subframe == 1) {
|
||||||
|
pusch_subframe = (7);
|
||||||
|
} else if (subframe == 5) {
|
||||||
|
pusch_subframe = (8);
|
||||||
|
} else {
|
||||||
|
AssertFatal(1==0,"phich.c: phich_subframe2_pusch_subframe, illegal subframe %d for tdd_config %d\n",
|
||||||
|
subframe,frame_parms->tdd_config);
|
||||||
|
pusch_subframe = (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
AssertFatal(1==0, "no implementation for TDD UL/DL-config = %d!\n", frame_parms->tdd_config);
|
||||||
|
pusch_subframe = (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_D(PHY, "subframe %d: PUSCH subframe = %d\n", subframe, pusch_subframe);
|
||||||
|
return pusch_subframe;
|
||||||
|
}
|
||||||
|
|
||||||
|
int check_pcfich(LTE_DL_FRAME_PARMS *frame_parms,uint16_t reg)
|
||||||
|
{
|
||||||
|
|
||||||
|
if ((reg == frame_parms->pcfich_reg[0]) ||
|
||||||
|
(reg == frame_parms->pcfich_reg[1]) ||
|
||||||
|
(reg == frame_parms->pcfich_reg[2]) ||
|
||||||
|
(reg == frame_parms->pcfich_reg[3]))
|
||||||
|
return(1);
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void generate_phich_reg_mapping(LTE_DL_FRAME_PARMS *frame_parms)
|
||||||
|
{
|
||||||
|
|
||||||
|
unsigned short n0 = (frame_parms->N_RB_DL * 2) - 4; // 2 REG per RB less the 4 used by PCFICH in first symbol
|
||||||
|
unsigned short n1 = (frame_parms->N_RB_DL * 3); // 3 REG per RB in second and third symbol
|
||||||
|
unsigned short n2 = n1;
|
||||||
|
unsigned short mprime = 0;
|
||||||
|
unsigned short Ngroup_PHICH;
|
||||||
|
// uint16_t *phich_reg = frame_parms->phich_reg;
|
||||||
|
uint16_t *pcfich_reg = frame_parms->pcfich_reg;
|
||||||
|
|
||||||
|
// compute Ngroup_PHICH (see formula at beginning of Section 6.9 in 36-211
|
||||||
|
Ngroup_PHICH = (frame_parms->phich_config_common.phich_resource*frame_parms->N_RB_DL)/48;
|
||||||
|
|
||||||
|
|
||||||
|
if (((frame_parms->phich_config_common.phich_resource*frame_parms->N_RB_DL)%48) > 0)
|
||||||
|
Ngroup_PHICH++;
|
||||||
|
|
||||||
|
// check if Extended prefix
|
||||||
|
if (frame_parms->Ncp == 1) {
|
||||||
|
Ngroup_PHICH<<=1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_PHICH
|
||||||
|
LOG_D(PHY,"Ngroup_PHICH %d (phich_config_common.phich_resource %d,phich_config_common.phich_duration %s, NidCell %d,Ncp %d, frame_type %d), smallest pcfich REG %d, n0 %d, n1 %d (first PHICH REG %d)\n",
|
||||||
|
((frame_parms->Ncp == NORMAL)?Ngroup_PHICH:(Ngroup_PHICH>>1)),
|
||||||
|
frame_parms->phich_config_common.phich_resource,
|
||||||
|
frame_parms->phich_config_common.phich_duration==normal?"normal":"extended",
|
||||||
|
frame_parms->Nid_cell,frame_parms->Ncp,frame_parms->frame_type,
|
||||||
|
pcfich_reg[frame_parms->pcfich_first_reg_idx],
|
||||||
|
n0,
|
||||||
|
n1,
|
||||||
|
((frame_parms->Nid_cell))%n0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// This is the algorithm from Section 6.9.3 in 36-211, it works only for normal PHICH duration for now ...
|
||||||
|
|
||||||
|
for (mprime=0;
|
||||||
|
mprime<((frame_parms->Ncp == NORMAL)?Ngroup_PHICH:(Ngroup_PHICH>>1));
|
||||||
|
mprime++) {
|
||||||
|
|
||||||
|
if (frame_parms->phich_config_common.phich_duration==normal) { // normal PHICH duration
|
||||||
|
|
||||||
|
frame_parms->phich_reg[mprime][0] = (frame_parms->Nid_cell + mprime)%n0;
|
||||||
|
|
||||||
|
if (frame_parms->phich_reg[mprime][0]>=pcfich_reg[frame_parms->pcfich_first_reg_idx])
|
||||||
|
frame_parms->phich_reg[mprime][0]++;
|
||||||
|
|
||||||
|
if (frame_parms->phich_reg[mprime][0]>=pcfich_reg[(frame_parms->pcfich_first_reg_idx+1)&3])
|
||||||
|
frame_parms->phich_reg[mprime][0]++;
|
||||||
|
|
||||||
|
if (frame_parms->phich_reg[mprime][0]>=pcfich_reg[(frame_parms->pcfich_first_reg_idx+2)&3])
|
||||||
|
frame_parms->phich_reg[mprime][0]++;
|
||||||
|
|
||||||
|
if (frame_parms->phich_reg[mprime][0]>=pcfich_reg[(frame_parms->pcfich_first_reg_idx+3)&3])
|
||||||
|
frame_parms->phich_reg[mprime][0]++;
|
||||||
|
|
||||||
|
frame_parms->phich_reg[mprime][1] = (frame_parms->Nid_cell + mprime + (n0/3))%n0;
|
||||||
|
|
||||||
|
|
||||||
|
if (frame_parms->phich_reg[mprime][1]>=pcfich_reg[frame_parms->pcfich_first_reg_idx])
|
||||||
|
frame_parms->phich_reg[mprime][1]++;
|
||||||
|
|
||||||
|
if (frame_parms->phich_reg[mprime][1]>=pcfich_reg[(frame_parms->pcfich_first_reg_idx+1)&3])
|
||||||
|
frame_parms->phich_reg[mprime][1]++;
|
||||||
|
|
||||||
|
if (frame_parms->phich_reg[mprime][1]>=pcfich_reg[(frame_parms->pcfich_first_reg_idx+2)&3])
|
||||||
|
frame_parms->phich_reg[mprime][1]++;
|
||||||
|
|
||||||
|
if (frame_parms->phich_reg[mprime][1]>=pcfich_reg[(frame_parms->pcfich_first_reg_idx+3)&3])
|
||||||
|
frame_parms->phich_reg[mprime][1]++;
|
||||||
|
|
||||||
|
|
||||||
|
frame_parms->phich_reg[mprime][2] = (frame_parms->Nid_cell + mprime + (2*n0/3))%n0;
|
||||||
|
|
||||||
|
if (frame_parms->phich_reg[mprime][2]>=pcfich_reg[frame_parms->pcfich_first_reg_idx])
|
||||||
|
frame_parms->phich_reg[mprime][2]++;
|
||||||
|
|
||||||
|
if (frame_parms->phich_reg[mprime][2]>=pcfich_reg[(frame_parms->pcfich_first_reg_idx+1)&3])
|
||||||
|
frame_parms->phich_reg[mprime][2]++;
|
||||||
|
|
||||||
|
if (frame_parms->phich_reg[mprime][2]>=pcfich_reg[(frame_parms->pcfich_first_reg_idx+2)&3])
|
||||||
|
frame_parms->phich_reg[mprime][2]++;
|
||||||
|
|
||||||
|
if (frame_parms->phich_reg[mprime][2]>=pcfich_reg[(frame_parms->pcfich_first_reg_idx+3)&3])
|
||||||
|
frame_parms->phich_reg[mprime][2]++;
|
||||||
|
|
||||||
|
#ifdef DEBUG_PHICH
|
||||||
|
printf("phich_reg :%d => %d,%d,%d\n",mprime,frame_parms->phich_reg[mprime][0],frame_parms->phich_reg[mprime][1],frame_parms->phich_reg[mprime][2]);
|
||||||
|
#endif
|
||||||
|
} else { // extended PHICH duration
|
||||||
|
frame_parms->phich_reg[mprime<<1][0] = (frame_parms->Nid_cell + mprime)%n0;
|
||||||
|
frame_parms->phich_reg[1+(mprime<<1)][0] = (frame_parms->Nid_cell + mprime)%n0;
|
||||||
|
|
||||||
|
frame_parms->phich_reg[mprime<<1][1] = ((frame_parms->Nid_cell*n1/n0) + mprime + (n1/3))%n1;
|
||||||
|
frame_parms->phich_reg[mprime<<1][2] = ((frame_parms->Nid_cell*n2/n0) + mprime + (2*n2/3))%n2;
|
||||||
|
|
||||||
|
frame_parms->phich_reg[1+(mprime<<1)][1] = ((frame_parms->Nid_cell*n1/n0) + mprime + (n1/3))%n1;
|
||||||
|
frame_parms->phich_reg[1+(mprime<<1)][2] = ((frame_parms->Nid_cell*n2/n0) + mprime + (2*n2/3))%n2;
|
||||||
|
//#ifdef DEBUG_PHICH
|
||||||
|
printf("phich_reg :%d => %d,%d,%d\n",mprime<<1,frame_parms->phich_reg[mprime<<1][0],frame_parms->phich_reg[mprime][1],frame_parms->phich_reg[mprime][2]);
|
||||||
|
printf("phich_reg :%d => %d,%d,%d\n",1+(mprime<<1),frame_parms->phich_reg[1+(mprime<<1)][0],frame_parms->phich_reg[1+(mprime<<1)][1],frame_parms->phich_reg[1+(mprime<<1)][2]);
|
||||||
|
//#endif
|
||||||
|
}
|
||||||
|
} // mprime loop
|
||||||
|
} // num_pdcch_symbols loop
|
||||||
Reference in New Issue
Block a user