pucch_pc.c 4.02 KB
Newer Older
1
/*******************************************************************************
2
    OpenAirInterface
ghaddab's avatar
ghaddab committed
3
    Copyright(c) 1999 - 2014 Eurecom
4

ghaddab's avatar
ghaddab committed
5 6 7 8
    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.
9 10


ghaddab's avatar
ghaddab committed
11 12 13 14
    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.
15

ghaddab's avatar
ghaddab committed
16
    You should have received a copy of the GNU General Public License
17 18
    along with OpenAirInterface.The full GNU General Public License is
   included in this distribution in the file called "COPYING". If not,
ghaddab's avatar
ghaddab committed
19
   see <http://www.gnu.org/licenses/>.
20 21

  Contact Information
ghaddab's avatar
ghaddab committed
22 23 24
  OpenAirInterface Admin: openair_admin@eurecom.fr
  OpenAirInterface Tech : openair_tech@eurecom.fr
  OpenAirInterface Dev  : openair4g-devel@eurecom.fr
25

ghaddab's avatar
ghaddab committed
26
  Address      : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
27

ghaddab's avatar
ghaddab committed
28
 *******************************************************************************/
29 30

/*! \file pusch_pc.c
31
 * \brief Implementation of UE PUSCH Power Control procedures from 36.213 LTE specifications (Section
32 33 34 35 36 37 38 39 40 41 42 43 44
 * \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"

45 46
int8_t pucch_power_cntl(PHY_VARS_UE *phy_vars_ue,uint8_t subframe,uint8_t eNB_id,PUCCH_FMT_t pucch_fmt)
{
47

48 49
  int8_t Po_PUCCH;
  uint8_t harq_pid;
50 51

  // P_pucch =  P_opucch+ PL + h(nCQI,nHARQ) + delta_pucchF(pucch_fmt) + g(i))
52 53
  //
  if ((pucch_fmt == pucch_format1a) ||
54 55
      (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;
56
    phy_vars_ue->g_pucch[eNB_id] += phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->delta_PUCCH;
57 58 59 60
  }

  phy_vars_ue->g_pucch[eNB_id] = 0;

knopp's avatar
knopp committed
61
  Po_PUCCH = get_PL(phy_vars_ue->Mod_id,phy_vars_ue->CC_id,eNB_id)+
62
             phy_vars_ue->lte_frame_parms.ul_power_control_config_common.p0_NominalPUCCH+
63 64
             phy_vars_ue->g_pucch[eNB_id];

65 66 67 68 69 70
  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;
71

72 73 74 75
  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;
76

77 78 79 80 81
  case pucch_format2:
    switch (phy_vars_ue->lte_frame_parms.ul_power_control_config_common.deltaF_PUCCH_Format2a) {
    case 0:
      Po_PUCCH -= 2;
      break;
82

83 84 85
    case 2:
      Po_PUCCH += 1;
      break;
86

87 88 89
    case 3:
      Po_PUCCH += 2;
      break;
90

91 92 93 94
    case 1:
    default:
      break;
    }
95

96 97
    break;
  }
98

99 100
  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",
101 102 103 104 105 106 107
          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 {
108
    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",
109 110 111 112 113 114
          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]);
115
  }
116

117 118
  return(Po_PUCCH);
}