/******************************************************************************* 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 . Contact Information OpenAirInterface Admin: openair_admin@eurecom.fr OpenAirInterface Tech : openair_tech@eurecom.fr OpenAirInterface Dev : openair4g-devel@eurecom.fr Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE *******************************************************************************/ /*! \file pusch_pc.c * \brief Implementation of UE PUSCH Power Control procedures from 36.213 LTE specifications (Section * \author R. Knopp * \date 2011 * \version 0.1 * \company Eurecom * \email: knopp@eurecom.fr * \note * \warning */ #include "PHY/defs.h" #include "PHY/LTE_TRANSPORT/proto.h" #include "PHY/extern.h" int8_t pucch_power_cntl(PHY_VARS_UE *phy_vars_ue,uint8_t subframe,uint8_t eNB_id,PUCCH_FMT_t pucch_fmt) { int8_t Po_PUCCH; uint8_t harq_pid; // P_pucch = P_opucch+ PL + h(nCQI,nHARQ) + delta_pucchF(pucch_fmt) + g(i)) // if ((pucch_fmt == pucch_format1a) || (pucch_fmt == pucch_format1b)) { // Update g_pucch based on TPC/delta_PUCCH received in PDCCH for this process harq_pid = phy_vars_ue->dlsch_ue[eNB_id][0]->harq_ack[subframe].harq_id; phy_vars_ue->g_pucch[eNB_id] += phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->delta_PUCCH; } phy_vars_ue->g_pucch[eNB_id] = 0; Po_PUCCH = get_PL(phy_vars_ue->Mod_id,phy_vars_ue->CC_id,eNB_id)+ phy_vars_ue->lte_frame_parms.ul_power_control_config_common.p0_NominalPUCCH+ phy_vars_ue->g_pucch[eNB_id]; switch (pucch_fmt) { case pucch_format1: case pucch_format2a: case pucch_format2b: Po_PUCCH += (-2+(phy_vars_ue->lte_frame_parms.ul_power_control_config_common.deltaF_PUCCH_Format1<<1)); break; case pucch_format1a: case pucch_format1b: Po_PUCCH += (1+(phy_vars_ue->lte_frame_parms.ul_power_control_config_common.deltaF_PUCCH_Format1b<<1)); break; case pucch_format2: switch (phy_vars_ue->lte_frame_parms.ul_power_control_config_common.deltaF_PUCCH_Format2a) { case 0: Po_PUCCH -= 2; break; case 2: Po_PUCCH += 1; break; case 3: Po_PUCCH += 2; break; case 1: default: break; } break; } if (pucch_fmt!=pucch_format1) { LOG_D(PHY,"[UE %d][PDSCH %x] frame %d, subframe %d: Po_PUCCH %d dBm : Po_NOMINAL_PUCCH %d dBm, PL %d dB, g_pucch %d dB\n", phy_vars_ue->Mod_id, phy_vars_ue->dlsch_ue[eNB_id][0]->rnti,phy_vars_ue->frame_tx,subframe, Po_PUCCH, phy_vars_ue->lte_frame_parms.ul_power_control_config_common.p0_NominalPUCCH, get_PL(phy_vars_ue->Mod_id,phy_vars_ue->CC_id,eNB_id), phy_vars_ue->g_pucch[eNB_id]); } else { LOG_D(PHY,"[UE %d][SR %x] frame %d, subframe %d: Po_PUCCH %d dBm : Po_NOMINAL_PUCCH %d dBm, PL %d dB g_pucch %d dB\n", phy_vars_ue->Mod_id, phy_vars_ue->dlsch_ue[eNB_id][0]->rnti,phy_vars_ue->frame_tx,subframe, Po_PUCCH, phy_vars_ue->lte_frame_parms.ul_power_control_config_common.p0_NominalPUCCH, get_PL(phy_vars_ue->Mod_id,phy_vars_ue->CC_id,eNB_id), phy_vars_ue->g_pucch[eNB_id]); } return(Po_PUCCH); }