diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index ef57403da9..7fcd6b07ab 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1309,6 +1309,7 @@ set(PHY_SRC_UE ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/dci_nr.c ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/dci_tools_nr.c + ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/pucch_nr.c ${OPENAIR1_DIR}/PHY/NR_REFSIG/ul_ref_seq_nr.c ${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_dmrs_rx.c ${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gold_ue.c diff --git a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c new file mode 100644 index 0000000000..9172c50e11 --- /dev/null +++ b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c @@ -0,0 +1,1466 @@ +/* + * 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/NR_UE_TRANSPORT/pucch_nr.c +* \brief Top-level routines for generating and decoding the PUCCH physical channel +* \author A. Mico Pereperez +* \date 2018 +* \version 0.1 +* \company Eurecom +* \email: +* \note +* \warning +*/ +//#include "PHY/defs.h" +#include "PHY/impl_defs_nr.h" +#include "PHY/defs_nr_common.h" +//#include "PHY/extern.h" +//#include "LAYER2/MAC/extern.h" + +#include "UTIL/LOG/log.h" +#include "UTIL/LOG/vcd_signal_dumper.h" + +#include "T.h" +#define DEBUG_PUCCH_TX +#define DEBUG_NR_PUCCH_TX +#define ONE_OVER_SQRT2 23170 // 32767/sqrt(2) = 23170 (ONE_OVER_SQRT2) + + /* + * The following tables implement TS 38.211 Subclause 5.2.2.2 Base sequences of length less than 36 (rows->u {0,1,..,29} / columns->n {0,1,...,M_ZC-1) + * Where base sequence r_u_v(n)=exp[j*phi(n)*pi/4] 0<=n<=M_ZC-1 and M_ZC={6,12,18,24} + * For M_ZC=30, base sequence r_u_v(n)=exp[-j((pi*[u+1]*[n+1]*[n+2])/31)] + */ + int16_t table_5_2_2_2_1_Re[30][6]={ // Table 5.2.2.2-1 (Re part) TS 38.211 Subclause 5.2.2.2 Base sequences of length less than 36 (M_ZC=6) + {-23170, 23170,-23170,-23170, 23170,-23170}, + {-23170,-23170, 23170, 23170,-23170,-23170}, + {-23170,-23170,-23170,-23170, 23170,-23170}, + { 23170, 23170, 23170,-23170, 23170,-23170}, + { 23170, 23170, 23170,-23170, 23170,-23170}, + {-23170, 23170, 23170,-23170,-23170,-23170}, + {-23170, 23170,-23170,-23170,-23170,-23170}, + {-23170, 23170, 23170,-23170, 23170, 23170}, + {-23170, 23170,-23170, 23170,-23170,-23170}, + {-23170,-23170, 23170,-23170,-23170,-23170}, + {-23170, 23170,-23170, 23170,-23170,-23170}, + {-23170, 23170,-23170, 23170, 23170,-23170}, + { 23170, 23170,-23170, 23170,-23170,-23170}, + { 23170, 23170,-23170,-23170, 23170,-23170}, + { 23170, 23170, 23170,-23170,-23170, 23170}, + { 23170, 23170, 23170, 23170,-23170,-23170}, + {-23170, 23170, 23170, 23170,-23170, 23170}, + {-23170,-23170, 23170, 23170, 23170,-23170}, + {-23170,-23170,-23170, 23170,-23170, 23170}, + {-23170, 23170, 23170,-23170, 23170,-23170}, + {-23170,-23170,-23170, 23170, 23170,-23170}, + {-23170, 23170,-23170,-23170,-23170, 23170}, + { 23170, 23170,-23170,-23170, 23170,-23170}, + { 23170, 23170,-23170,-23170, 23170,-23170}, + { 23170, 23170,-23170, 23170,-23170,-23170}, + { 23170, 23170,-23170, 23170,-23170,-23170}, + { 23170, 23170, 23170, 23170,-23170, 23170}, + { 23170, 23170, 23170,-23170, 23170, 23170}, + { 23170, 23170, 23170,-23170,-23170, 23170}, + { 23170, 23170,-23170, 23170, 23170, 23170} + }; + int16_t table_5_2_2_2_1_Im[30][6]={ // Table 5.2.2.2-1 (Im part) TS 38.211 Subclause 5.2.2.2 Base sequences of length less than 36 (M_ZC=6) + {-23170,-23170, 23170, 23170,-23170,-23170}, + {-23170, 23170,-23170,-23170, 23170,-23170}, + {-23170,-23170,-23170, 23170, 23170,-23170}, + { 23170, 23170, 23170, 23170,-23170,-23170}, + { 23170, 23170, 23170,-23170,-23170, 23170}, + {-23170, 23170,-23170,-23170,-23170,-23170}, + {-23170, 23170, 23170,-23170,-23170,-23170}, + {-23170,-23170, 23170,-23170, 23170,-23170}, + {-23170,-23170,-23170, 23170,-23170,-23170}, + {-23170,-23170, 23170,-23170, 23170,-23170}, + {-23170, 23170, 23170, 23170,-23170,-23170}, + {-23170,-23170,-23170, 23170, 23170,-23170}, + { 23170, 23170, 23170,-23170,-23170, 23170}, + { 23170, 23170, 23170, 23170,-23170, 23170}, + { 23170, 23170, 23170,-23170, 23170,-23170}, + { 23170, 23170, 23170,-23170, 23170,-23170}, + {-23170,-23170,-23170,-23170, 23170,-23170}, + {-23170,-23170,-23170, 23170,-23170,-23170}, + {-23170,-23170,-23170, 23170,-23170,-23170}, + {-23170, 23170, 23170,-23170,-23170,-23170}, + {-23170, 23170,-23170, 23170, 23170,-23170}, + {-23170, 23170,-23170,-23170,-23170,-23170}, + { 23170, 23170,-23170, 23170, 23170, 23170}, + { 23170, 23170,-23170,-23170, 23170,-23170}, + { 23170, 23170, 23170,-23170, 23170, 23170}, + { 23170, 23170,-23170, 23170, 23170, 23170}, + { 23170, 23170,-23170,-23170, 23170,-23170}, + { 23170, 23170,-23170, 23170,-23170,-23170}, + { 23170, 23170,-23170, 23170,-23170,-23170}, + { 23170, 23170,-23170, 23170,-23170,-23170} + }; + int16_t table_5_2_2_2_2_Re[30][12]={ // Table 5.2.2.2-2 (Re part) TS 38.211 Subclause 5.2.2.2 Base sequences of length less than 36 (M_ZC=12) + {-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170}, + {-23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170}, + {-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170}, + {-23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170}, + {-23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170}, + {-23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170,-23170}, + { 23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170}, + { 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170}, + {-23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170}, + {-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170}, + {-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170}, + {-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170}, + {-23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170}, + {-23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170}, + { 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170}, + {-23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170}, + { 23170, 23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170}, + { 23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170}, + {-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170}, + {-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170}, + {-23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170}, + {-23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170}, + {-23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170}, + {-23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170}, + {-23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170}, + {-23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170}, + { 23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170, 23170}, + {-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170}, + { 23170, 23170,-23170, 23170, 23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170}, + {-23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170} + }; + int16_t table_5_2_2_2_2_Im[30][12]={ // Table 5.2.2.2-2 (Im part) TS 38.211 Subclause 5.2.2.2 Base sequences of length less than 36 (M_ZC=12) + {-23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170}, + {-23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170}, + {-23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170}, + {-23170,-23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170}, + {-23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170}, + {-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170}, + { 23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170}, + {-23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170}, + {-23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170}, + {-23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170}, + {-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170}, + {-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170}, + {-23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170}, + {-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170}, + { 23170, 23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170}, + {-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170}, + {-23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170}, + {-23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170}, + {-23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170}, + {-23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170}, + { 23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170}, + {-23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170}, + {-23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170}, + { 23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170}, + {-23170,-23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170}, + {-23170, 23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170, 23170}, + {-23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170}, + {-23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170, 23170, 23170,-23170}, + { 23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170}, + {-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170} + }; + int16_t table_5_2_2_2_3_Re[30][6]={ // Table 5.2.2.2-3 (Re part) TS 38.211 Subclause 5.2.2.2 Base sequences of length less than 36 (M_ZC=18) + { 23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170, 23170, 23170, 23170}, + {-23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170}, + {-23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170}, + {-23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170}, + { 23170, 23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170, 23170}, + {-23170,-23170, 23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170}, + {-23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170}, + { 23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170}, + {-23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170}, + {-23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170}, + {-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170}, + {-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170}, + {-23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170}, + { 23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170,-23170, 23170}, + {-23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170, 23170, 23170}, + {-23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170}, + {-23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170}, + {-23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170}, + {-23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170}, + {-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170}, + {-23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170}, + { 23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170}, + {-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170}, + {-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170}, + {-23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170}, + {-23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170}, + {-23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170}, + {-23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170}, + { 23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170}, + {-23170,-23170, 23170, 23170, 23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170} + }; + int16_t table_5_2_2_2_3_Im[30][6]={ // Table 5.2.2.2-3 (Im part) TS 38.211 Subclause 5.2.2.2 Base sequences of length less than 36 (M_ZC=18) + {-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170}, + { 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170}, + {-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170}, + {-23170,-23170, 23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170}, + { 23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170}, + { 23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170}, + {-23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170}, + { 23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170}, + {-23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170}, + { 23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170,-23170}, + {-23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170}, + {-23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170}, + {-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170, 23170}, + { 23170, 23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170}, + {-23170, 23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170, 23170}, + { 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170}, + {-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170}, + {-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170}, + {-23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170}, + { 23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170}, + {-23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170}, + { 23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170}, + {-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170, 23170}, + { 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170}, + { 23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170}, + {-23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170}, + {-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170}, + {-23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170}, + {-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170, 23170}, + {-23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170} + }; + int16_t table_5_2_2_2_4_Re[30][6]={ // Table 5.2.2.2-4 (Re part) TS 38.211 Subclause 5.2.2.2 Base sequences of length less than 36 (M_ZC=24) + { 23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170}, + { 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170}, + { 23170,-23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170}, + { 23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170}, + { 23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170}, + {-23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170}, + {-23170,-23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170,-23170}, + {-23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170}, + {-23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170}, + { 23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170}, + {-23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170}, + {-23170,-23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170}, + {-23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170}, + {-23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170}, + {-23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170}, + {-23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170}, + {-23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170}, + {-23170, 23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170}, + {-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170}, + {-23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170}, + {-23170,-23170, 23170, 23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170}, + {-23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170}, + {-23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170}, + {-23170, 23170, 23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170}, + {-23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170}, + {-23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170}, + { 23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170}, + {-23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170}, + {-23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170}, + {-23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170} + }; + int16_t table_5_2_2_2_4_Im[30][6]={ // Table 5.2.2.2-4 (Im part) TS 38.211 Subclause 5.2.2.2 Base sequences of length less than 36 (M_ZC=24) + {-23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170}, + {-23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170}, + {-23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170}, + { 23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170}, + {-23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170}, + {-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170}, + {-23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170}, + {-23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170}, + {-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170}, + { 23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170}, + {-23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170}, + {-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170,-23170}, + { 23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170}, + {-23170, 23170,-23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170}, + {-23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170}, + {-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170}, + {-23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170}, + { 23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170}, + {-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170}, + {-23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170}, + {-23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170}, + { 23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170}, + {-23170, 23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170}, + {-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170}, + {-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170}, + {-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170}, + {-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170}, + { 23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170}, + {-23170, 23170,-23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170}, + { 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170} + }; +void nr_group_sequence_hopping (uint8_t PUCCH_GroupHopping, + uint32_t n_id, + uint8_t n_hop, + uint8_t nr_tti_rx, + uint8_t *u, + uint8_t *v) { +/* + * Implements TS 38.211 subclause 6.3.2.2.1 Group and sequence hopping + * The following variables are set by higher layers: + * - PUCCH_GroupHopping: + * - n_id: higher-layer parameter hoppingId + * - n_hop: frequency hopping index + * if intra-slot frequency hopping is disabled by the higher-layer parameter PUCCH-frequency-hopping + * n_hop=0 + * if frequency hopping is enabled by the higher-layer parameter PUCCH-frequency-hopping + * n_hop=0 for the first hop + * n_hop=1 for the second hop + */ + uint8_t f_ss=0,f_gh=0; + *u=0; + *v=0; + uint32_t c_init = (1<<5)*floor(n_id/30)+(n_id%30); // we initialize c_init to calculate u,v + uint32_t x1,s = lte_gold_generic(&x1, &c_init, 1); // TS 38.211 Subclause 5.2.1 + #ifdef DEBUG_NR_PUCCH_TX + printf("\t\t [nr_group_sequence_hopping] calculating u,v -> "); + #endif + + if (PUCCH_GroupHopping == 0){ // PUCCH_GroupHopping 'neither' + f_ss = n_id%30; + } + if (PUCCH_GroupHopping == 1){ // PUCCH_GroupHopping 'enabled' + for (int m=0; m<8; m++){ + f_gh = f_gh + ((1<>(8*(2*nr_tti_rx+n_hop)+m))&1))); // Not sure we have to use nr_tti_rx FIXME!!! + } + f_gh = f_gh%30; + f_ss = n_id%30; + } + if (PUCCH_GroupHopping == 2){ // PUCCH_GroupHopping 'disabled' + f_ss = n_id%30; + *v = (uint8_t)((s>>(2*nr_tti_rx+n_hop))&1); // Not sure we have to use nr_tti_rx FIXME!!! + } + *u = (f_gh+f_ss)%30; + #ifdef DEBUG_NR_PUCCH_TX + printf("%d,%d\n",*u,*v); + #endif +} +double nr_cyclic_shift_hopping(uint32_t n_id, + uint8_t m0, + uint8_t mcs, + uint8_t lnormal, + uint8_t lprime, + uint8_t nr_tti_rx) { +/* + * Implements TS 38.211 subclause 6.3.2.2.2 Cyclic shift hopping + * - n_id: higher-layer parameter hoppingId + * - m0: provided by higher layer parameter PUCCH-F0-F1-initial-cyclic-shift of PUCCH-F0-resource-config + * - mcs: mcs=0 except for PUCCH format 0 when it depends on information to be transmitted according to TS 38.213 subclause 9.2 + * - lnormal: lnormal is the OFDM symbol number in the PUCCH transmission where l=0 corresponds to the first OFDM symbol of the PUCCH transmission + * - lprime: lprime is the index of the OFDM symbol in the slot that corresponds to the first OFDM symbol of the PUCCH transmission in the slot given by [5, TS 38.213] + */ + // alpha_init initialized to 2*PI/12=0.5235987756 + double alpha = 0.5235987756; + uint32_t c_init = n_id; // we initialize c_init again to calculate n_cs + uint32_t x1,s = lte_gold_generic(&x1, &c_init, 1); // TS 38.211 Subclause 5.2.1 + uint8_t n_cs=0; + #ifdef DEBUG_NR_PUCCH_TX + printf("\t\t [nr_cyclic_shift_hopping] calculating alpha (cyclic shift) -> "); + #endif + for (int m=0; m<8; m++){ + // calculating n_cs (Not sure we have to use nr_tti_rx FIXME!!!) + n_cs = n_cs+((1<>((14*8*nr_tti_rx) + 8*(lnormal+lprime) + m))&1))); + } + alpha = (alpha * (double)((m0+mcs+n_cs)%12)); + #ifdef DEBUG_NR_PUCCH_TX + printf("%lf\n",alpha); + #endif + return(alpha); +} +void nr_generate_pucch0(int32_t **txdataF, + NR_DL_FRAME_PARMS *frame_parms, + PUCCH_CONFIG_DEDICATED *pucch_config_dedicated, + int16_t amp, + uint8_t nr_tti_rx, + uint8_t mcs, + uint8_t nrofSymbols, + uint8_t startingSymbolIndex, + uint8_t startingPRB) { + #ifdef DEBUG_NR_PUCCH_TX + printf("\t [nr_generate_pucch0] start function\n"); + #endif + + /* + * Implement TS 38.211 Subclause 6.3.2.3.1 Sequence generation + * + */ + #ifdef DEBUG_NR_PUCCH_TX + printf("\t [nr_generate_pucch0] sequence generation\n"); + #endif + + // number of symbols defined in the PUCCH-Config from higher layers: format 0 {1-2} FIXME! + //uint8_t nrofSymbols; + //uint8_t startingSymbolIndex; + //uint8_t startingPRB; + + /* + * Defining cyclic shift hopping TS 38.211 Subclause 6.3.2.2.2 + */ + // alpha is cyclic shift + double alpha; + // m0 is provided by higher layer parameter PUCCH-F0-F1-initial-cyclic-shift of PUCCH-F0-resource-config + uint8_t m0; + // lnormal is the OFDM symbol number in the PUCCH transmission where l=0 corresponds to the first OFDM symbol of the PUCCH transmission + uint8_t lnormal; + // lprime is the index of the OFDM symbol in the slot that corresponds to the first OFDM symbol of the PUCCH transmission in the slot given by [5, TS 38.213] + uint8_t lprime; + // mcs is provided by TC 38.213 subclauses 9.2.3, 9.2.4, 9.2.5 FIXME! + //uint8_t mcs; + + /* + * in TS 38.213 Subclause 9.2.1 it is said that: + * for PUCCH format 0 or PUCCH format 1, the index of the cyclic shift + * is indicated by higher layer parameter PUCCH-F0-F1-initial-cyclic-shift + */ + + /* + * Implementing TS 38.211 Subclause 6.3.2.3.1, the sequence x(n) shall be generated according to: + * x(l*12+n) = r_u_v_alpha_delta(n) + */ + // the value of u,v (delta always 0 for PUCCH) has to be calculated according to TS 38.211 Subclause 6.3.2.2.1 + uint8_t u=0,v=0,delta=0; + // depending on the value of the PUCCH_GroupHopping, we will obtain different values for u,v + uint8_t PUCCH_GroupHopping; // from higher layers FIXME!! + // n_id is hoppingId from PUCCH-ConfigCommon: + // Cell-Specific scrambling ID for group hoppping and sequence hopping if enabled + // Corresponds to L1 parameter 'HoppingID' (see 38.211, section 6.3.2.2) BIT STRING (SIZE (10)) + uint32_t n_id; // from higher layers FIXME!! + // if frequency hopping is disabled by the higher-layer parameter PUCCH-frequency-hopping + // n_hop = 0 + // if frequency hopping is enabled by the higher-layer parameter PUCCH-frequency-hopping + // n_hop = 0 for first hop + // n_hop = 1 for second hop + uint8_t n_hop = 0; + uint8_t PUCCH_Frequency_Hopping; // from higher layers FIXME!! + + /////////////////////////////////////////////////////////// initializing some variables for test + m0=0; + PUCCH_GroupHopping=0; + n_id=10; + PUCCH_Frequency_Hopping = 0; + printf("\t [nr_generate_pucch0] sequence generation: variable initialization for test\n"); + /////////////////////////////////////////////////////// ending variables initialization for test + + // x_n contains the sequence r_u_v_alpha_delta(n) + int16_t x_n_re[24],x_n_im[24]; + // we proceed to calculate alpha according to TS 38.211 Subclause 6.3.2.2.2 + for (int l=0; l>15) + - (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15))); // Re part of base sequence shifted by alpha + x_n_im[(12*l)+n] = (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15) + + (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15))); // Im part of base sequence shifted by alpha + #ifdef DEBUG_NR_PUCCH_TX + printf("\t [nr_generate_pucch0] sequence generation \tu=%d \tv=%d \talpha=%lf \tx_n(l=%d,n=%d)=(%d,%d)\n", + u,v,alpha,l,n,x_n_re[(12*l)+n],x_n_im[(12*l)+n]); + #endif + } + } + /* + * Implementing TS 38.211 Subclause 6.3.2.3.2 Mapping to physical resources FIXME! + */ + int32_t *txptr; + uint32_t re_offset; + for (int l=0; lN_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is lower band + re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset; + } + if ((startingPRB >= (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is upper band + re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(startingPRB-(frame_parms->N_RB_DL>>1))); + } + if ((startingPRB < (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB is lower band + re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset; + } + if ((startingPRB > (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB is upper band + re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(startingPRB-(frame_parms->N_RB_DL>>1))) + 6; + } + if ((startingPRB == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB contains DC + re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset; + } + txptr = &txdataF[0][re_offset]; + for (int n=0; n<12; n++){ + if ((n==6) && (startingPRB == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { + // if number RBs in bandwidth is odd and current PRB contains DC, we need to recalculate the offset when n=6 (for second half PRB) + re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size); + } + ((int16_t *)&txdataF[0][re_offset])[0] = (int16_t)(((int32_t)(amp) * x_n_re[(12*l)+n])>>15); + ((int16_t *)&txdataF[0][re_offset])[1] = (int16_t)(((int32_t)(amp) * x_n_im[(12*l)+n])>>15); + //((int16_t *)txptr[0][re_offset])[0] = (int16_t)((int32_t)amp * x_n_re[(12*l)+n])>>15; + //((int16_t *)txptr[0][re_offset])[1] = (int16_t)((int32_t)amp * x_n_im[(12*l)+n])>>15; + //txptr[re_offset] = (x_n_re[(12*l)+n]<<16) + x_n_im[(12*l)+n]; + #ifdef DEBUG_NR_PUCCH_TX + printf("\t [nr_generate_pucch0] mapping to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \ttxptr(%d)=(x_n(l=%d,n=%d)=(%d,%d))\n", + amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,re_offset, + l,n,((int16_t *)&txdataF[0][re_offset])[0],((int16_t *)&txdataF[0][re_offset])[1]); + #endif + re_offset++; + } + } +} +void nr_generate_pucch1(int32_t **txdataF, + NR_DL_FRAME_PARMS *frame_parms, + PUCCH_CONFIG_DEDICATED *pucch_config_dedicated, + uint64_t payload, + int16_t amp, + uint8_t nr_tti_rx, + uint8_t nrofSymbols, + uint8_t startingSymbolIndex, + uint8_t startingPRB, + uint8_t startingPRB_intraSlotHopping, + uint8_t timeDomainOCC, + uint8_t nr_bit) { +#ifdef DEBUG_NR_PUCCH_TX + printf("\t [nr_generate_pucch1] start function\n"); +#endif + + /* + * The following tables implement TS 38.211 table 6.3.2.4.1-1: Number of PUCCH symbols and the corresponding N_SF_mprime_PUCCH_1 + * One table for no intra-slot hopping + * Two tables for intra-slot hopping (mprime=0 and mprime=1) + */ + uint8_t table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_noHop[14] = {0,0,0,2,2,3,3,4,4,5,5,6,6,7}; // for index PUCCH-length, we obtain N_SF_mprime_PUCCH_1 when no intra-slot hopping + uint8_t table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_m0Hop[14] = {0,0,0,1,1,1,1,2,2,2,2,3,3,3}; // for index PUCCH-length, we obtain N_SF_mprime_PUCCH_1 when intra-slot hopping and mprime=0 + uint8_t table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_m1Hop[14] = {0,0,0,1,1,2,2,2,2,3,3,3,3,4}; // for index PUCCH-length, we obtain N_SF_mprime_PUCCH_1 when intra-slot hopping and mprime=1 + /* + * The following tables implement TS 38.211 table 6.4.1.3.1.1-1: Number of DM-RS symbols and the corresponding N_SF_mprime_PUCCH_1 + * One table for no intra-slot hopping + * Two tables for intra-slot hopping (mprime=0 and mprime=1) + */ + uint8_t table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_noHop[14] = {0,0,0,2,3,3,4,4,5,5,6,6,7,7}; // for index PUCCH-DM-RS-length, we obtain N_SF_mprime_PUCCH_1 when no intra-slot hopping + uint8_t table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_m0Hop[14] = {0,0,0,1,1,2,2,2,2,3,3,3,3,4}; // for index PUCCH-DM-RS-length, we obtain N_SF_mprime_PUCCH_1 when intra-slot hopping and mprime=0 + uint8_t table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_m1Hop[14] = {0,0,0,1,2,1,2,2,3,2,3,3,4,3}; // for index PUCCH-DM-RS-length, we obtain N_SF_mprime_PUCCH_1 when intra-slot hopping and mprime=1 +/* The following tables implement TS 38.211 table 6.3.2.4.1-2: Orthogonal sequences wi(m)=exp(j*2*pi*phi(m)/N_SF) for PUCCH format 1 + uint16_t table_6_3_2_4_1_2_W2[2][2] = {{0,0}, {0,1}}; + uint16_t table_6_3_2_4_1_2_W3[3][3] = {{0,0,0}, {0,1,2}, {0,2,1}}; + uint16_t table_6_3_2_4_1_2_W4[4][4] = {{0,0,0,0}, {0,2,0,2}, {0,0,2,2} , {0,2,2,0}}; + uint16_t table_6_3_2_4_1_2_W5[2][2] = {{0,0,0,0,0}, {0,1,2,3,4}, {0,2,4,1,3}, {0,3,1,4,2}, {0,4,3,2,1}}; + uint16_t table_6_3_2_4_1_2_W6[2][2] = {{0,0,0,0,0,0}, {0,1,2,3,4,5}, {0,2,4,0,2,4}, {0,3,0,3,0,3}, {0,4,2,0,4,2}, {0,5,4,3,2,1}}; + uint16_t table_6_3_2_4_1_2_W7[2][2] = {{0,0,0,0,0,0,0},{0,1,2,3,4,5,6},{0,2,4,6,1,3,5},{0,3,6,2,5,1,4},{0,4,1,5,2,6,3},{0,5,3,1,6,4,2},{0,6,5,4,3,2,1}}; +*/ + int16_t table_6_3_2_4_1_2_Wi_Re[8][7][7] = { + {{0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}}, + {{0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}}, + {{32767,32767,0,0,0,0,0}, {32767,-32767,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}}, + {{32767,32767,32767,0,0,0,0}, {32767,-16384,-16384,0,0,0,0}, {32767,-16384,-16384,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}}, + {{32767,32767,32767,32767,0,0,0}, {32767,-32767,32767,-32767,0,0,0}, {32767,32767,-32767,-32767,0,0,0}, {32767,-32767,-32767,32767,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}}, + {{32767,32767,32767,32767,32767,0,0}, {32767,10126,-26509,-26509,10126,0,0}, {32767,-26509,10126,10126,-26509,0,0}, {32767,-26509,10126,10126,-26509,0,0}, {32767,10126,-26509,-26509,10126,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}}, + {{32767,32767,32767,32767,32767,32767,0}, {32767,16384,-16384,-32767,-16384,16384,0}, {32767,-16384,-16384,32767,-16384,-16384,0}, {32767,-32767,32767,-32767,32767,-32767,0}, {32767,-16384,-16384,32767,-16384,-16384,0}, {32767,16384,-16384,-32767,-16384,16384,0}, {0,0,0,0,0,0,0}}, + {{32767,32767,32767,32767,32767,32767,32767},{32767,20430,-7291,-29522,-29522,-7291,20430},{32767,-7291,-29522,20430,20430,-29522,-7291},{32767,-29522,20430,-7291,-7291,20430,-29522},{32767,-29522,20430,-7291,-7291,20430,-29522},{32767,-7291,-29522,20430,20430,-29522,-7291},{32767,20430,-7291,-29522,-29522,-7291,20430}} + }; + int16_t table_6_3_2_4_1_2_Wi_Im[8][7][7] = { + {{0,0,0,0,0,0,0},{0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}}, + {{0,0,0,0,0,0,0},{0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}}, + {{0,0,0,0,0,0,0},{0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}}, + {{0,0,0,0,0,0,0},{0,28377,-28377,0,0,0,0}, {0,-28377,28377,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}}, + {{0,0,0,0,0,0,0},{0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}}, + {{0,0,0,0,0,0,0},{0,31163,19260,-19260,-31163,0,0}, {0,19260,-31163,31163,-19260,0,0}, {0,-19260,31163,-31163,19260,0,0}, {0,-31163,-19260,19260,31163,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}}, + {{0,0,0,0,0,0,0},{0,28377,28377,0,-28377,-28377,0}, {0,28377,-28377,0,28377,-28377,0}, {0,0,0,0,0,0,0}, {0,-28377,28377,0,-28377,28377,0}, {0,-28377,-28377,0,28377,28377,0}, {0,0,0,0,0,0,0}}, + {{0,0,0,0,0,0,0},{0,25618,31945,14217,-14217,-31945,-25618},{0,31945,-14217,-25618,25618,14217,-31945},{0,14217,-25618,31945,-31945,25618,-14217},{0,-14217,25618,-31945,31945,-25618,14217},{0,-31945,14217,25618,-25618,-14217,31945},{0,-25618,-31945,-14217,14217,31945,25618}} + }; + + /* + * Implement TS 38.211 Subclause 6.3.2.4.1 Sequence modulation + * + */ + // nr_bit = {1,2}, to be provided in function call. FIXME! + //uint8_t M_bit=1; +//#define ONE_OVER_SQRT2 23170 // 32767/sqrt(2) = 23170 (ONE_OVER_SQRT2) + // complex-valued symbol d_re, d_im containing complex-valued symbol d(0): + int16_t d_re, d_im; + if (nr_bit == 1){ // using BPSK if M_bit=1 according to TC 38.211 Subclause 5.1.2 + d_re = (payload&1)==0 ? (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15) : -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); + d_im = (payload&1)==0 ? (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15) : -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); + } + else { // using QPSK if M_bit=2 according to TC 38.211 Subclause 5.1.2 + if (((payload&1)==0) && (((payload>>1)&1)==0)) { + d_re = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); // 32767/sqrt(2) = 23170 (ONE_OVER_SQRT2) + d_im = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); + } + if (((payload&1)==0) && (((payload>>1)&1)==1)) { + d_re = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); + d_im = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); + } + if (((payload&1)==1) && (((payload>>1)&1)==0)) { + d_re = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); + d_im = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); + } + if (((payload&1)==1) && (((payload>>1)&1)==1)) { + d_re = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); + d_im = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); + } + } + #ifdef DEBUG_NR_PUCCH_TX + printf("\t [nr_generate_pucch1] sequence modulation: payload=%x \tde_re=%d \tde_im=%d\n",payload,d_re,d_im); + #endif + + /* + * Defining cyclic shift hopping TS 38.211 Subclause 6.3.2.2.2 + */ + // alpha is cyclic shift + double alpha; + // m0 is provided by higher layer parameter PUCCH-F0-F1-initial-cyclic-shift of PUCCH-F0-resource-config + uint8_t m0; + // lnormal is the OFDM symbol number in the PUCCH transmission where l=0 corresponds to the first OFDM symbol of the PUCCH transmission + uint8_t lnormal = 0 ; + // lprime is the index of the OFDM symbol in the slot that corresponds to the first OFDM symbol of the PUCCH transmission in the slot given by [5, TS 38.213] + uint8_t lprime = startingSymbolIndex; + // mcs = 0 except for PUCCH format 0 + uint8_t mcs=0; + // r_u_v_alpha_delta_re and r_u_v_alpha_delta_im tables containing the sequence for the DM-RS. + // When they are multiplied by d(0), they become the sequence y(n) for the PUCCH + int16_t r_u_v_alpha_delta_re[12],r_u_v_alpha_delta_im[12]; + /* + * in TS 38.213 Subclause 9.2.1 it is said that: + * for PUCCH format 0 or PUCCH format 1, the index of the cyclic shift + * is indicated by higher layer parameter PUCCH-F0-F1-initial-cyclic-shift + */ + + /* + * the complex-valued symbol d_0 shall be multiplied with a sequence r_u_v_alpha_delta(n): y(n) = d_0 * r_u_v_alpha_delta(n) + */ + // the value of u,v (delta always 0 for PUCCH) has to be calculated according to TS 38.211 Subclause 6.3.2.2.1 + uint8_t u=0,v=0,delta=0; + // depending on the value of the PUCCH_GroupHopping, we will obtain different values for u,v + uint8_t PUCCH_GroupHopping; // from higher layers FIXME!! + // n_id is hoppingId from PUCCH-ConfigCommon: + // Cell-Specific scrambling ID for group hoppping and sequence hopping if enabled + // Corresponds to L1 parameter 'HoppingID' (see 38.211, section 6.3.2.2) BIT STRING (SIZE (10)) + uint32_t n_id; // from higher layers FIXME!! + // if frequency hopping is disabled, intraSlotFrequencyHopping is not provided + // n_hop = 0 + // if frequency hopping is enabled, intraSlotFrequencyHopping is provided + // n_hop = 0 for first hop + // n_hop = 1 for second hop + uint8_t n_hop = 0; + // Intra-slot frequency hopping shall be assumed when the higher-layer parameter intraSlotFrequencyHopping is provided, + // regardless of whether the frequency-hop distance is zero or not, + // otherwise no intra-slot frequency hopping shall be assumed + //uint8_t PUCCH_Frequency_Hopping = 0 ; // from higher layers. Let's suppose we do not support intra-slot hopping FIXME!! + uint8_t intraSlotFrequencyHopping = 0; + // y_n contains the complex value d multiplied by the sequence r_u_v + int16_t y_n_re[12],y_n_im[12]; + nr_group_sequence_hopping(PUCCH_GroupHopping,n_id,n_hop,nr_tti_rx,&u,&v); // calculating u and v value + alpha = nr_cyclic_shift_hopping(n_id,m0,mcs,lnormal,lprime,nr_tti_rx); + for (int n=0; n<12; n++){ + r_u_v_alpha_delta_re[n] = (int16_t)((((int32_t)(round(32767*cos(alpha*n)))*table_5_2_2_2_2_Re[u][n])>>15) + - (((int32_t)(round(32767*sin(alpha*n)))*table_5_2_2_2_2_Im[u][n])>>15)); // Re part of base sequence shifted by alpha + r_u_v_alpha_delta_im[n] = (int16_t)((((int32_t)(round(32767*cos(alpha*n)))*table_5_2_2_2_2_Im[u][n])>>15) + + (((int32_t)(round(32767*sin(alpha*n)))*table_5_2_2_2_2_Re[u][n])>>15)); // Im part of base sequence shifted by alpha + // PUCCH sequence = DM-RS sequence multiplied by d(0) + y_n_re[n] = (int16_t)((((int32_t)(r_u_v_alpha_delta_re[n])*d_re)>>15) + - (((int32_t)(r_u_v_alpha_delta_im[n])*d_im)>>15)); // Re part of y(n) + y_n_im[n] = (int16_t)((((int32_t)(r_u_v_alpha_delta_re[n])*d_im)>>15) + + (((int32_t)(r_u_v_alpha_delta_im[n])*d_re)>>15)); // Im part of y(n) + // DM-RS sequence + r_u_v_alpha_delta_re[n] = (int16_t)(((int32_t)amp*r_u_v_alpha_delta_re[n])>>15); + r_u_v_alpha_delta_im[n] = (int16_t)(((int32_t)amp*r_u_v_alpha_delta_im[n])>>15); + #ifdef DEBUG_NR_PUCCH_TX + printf("\t [nr_generate_pucch1] sequence generation \tu=%d \tv=%d \talpha=%lf \tr_u_v_alpha_delta[n=%d]=(%d,%d) \ty_n[n=%d]=(%d,%d)\n", + u,v,alpha,n,r_u_v_alpha_delta_re[n],r_u_v_alpha_delta_im[n],n,y_n_re[n],y_n_im[n]); + #endif + } + /* + * The block of complex-valued symbols y(n) shall be block-wise spread with the orthogonal sequence wi(m) + * (defined in table_6_3_2_4_1_2_Wi_Re and table_6_3_2_4_1_2_Wi_Im) + * z(mprime*12*table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_noHop[pucch_symbol_length]+m*12+n)=wi(m)*y(n) + * + * The block of complex-valued symbols r_u_v_alpha_delta(n) for DM-RS shall be block-wise spread with the orthogonal sequence wi(m) + * (defined in table_6_3_2_4_1_2_Wi_Re and table_6_3_2_4_1_2_Wi_Im) + * z(mprime*12*table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_noHop[pucch_symbol_length]+m*12+n)=wi(m)*y(n) + * + * We are not implementing intra-slot hopping at the moment (so mprime=0)FIXME! + */ +#define MAX_SIZE_Z 168 // this value has to be calculated from mprime*12*table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_noHop[pucch_symbol_length]+m*12+n + int16_t z_re[MAX_SIZE_Z],z_im[MAX_SIZE_Z]; + int16_t z_dmrs_re[MAX_SIZE_Z],z_dmrs_im[MAX_SIZE_Z]; + // the orthogonal sequence index for wi(m) defined in TS 38.213 Subclause 9.2.1 + // the index of the orthogonal cover code is from a set determined as described in [4, TS 38.211] + // and is indicated by higher layer parameter PUCCH-F1-time-domain-OCC + // In the PUCCH_Config IE, the PUCCH-format1, timeDomainOCC field FIXME! + uint8_t w_index = timeDomainOCC; // to be filled with the value of timeDomainOCC, higher layers parameters FIXME !!! + // N_SF_mprime_PUCCH_1 contains N_SF_mprime from table 6.3.2.4.1-1 (depending on number of PUCCH symbols nrofSymbols, mprime and intra-slot hopping enabled/disabled) + uint8_t N_SF_mprime_PUCCH_1; + // N_SF_mprime_PUCCH_1 contains N_SF_mprime from table 6.4.1.3.1.1-1 (depending on number of PUCCH symbols nrofSymbols, mprime and intra-slot hopping enabled/disabled) + uint8_t N_SF_mprime_PUCCH_DMRS_1; + // N_SF_mprime_PUCCH_1 contains N_SF_mprime from table 6.3.2.4.1-1 (depending on number of PUCCH symbols nrofSymbols, mprime=0 and intra-slot hopping enabled/disabled) + uint8_t N_SF_mprime0_PUCCH_1; + // N_SF_mprime_PUCCH_1 contains N_SF_mprime from table 6.4.1.3.1.1-1 (depending on number of PUCCH symbols nrofSymbols, mprime=0 and intra-slot hopping enabled/disabled) + uint8_t N_SF_mprime0_PUCCH_DMRS_1; + // mprime is 0 if no intra-slot hopping / mprime is {0,1} if intra-slot hopping + uint8_t mprime = 0; + if (intraSlotFrequencyHopping == 0) { // intra-slot hopping disabled + #ifdef DEBUG_NR_PUCCH_TX + printf("\t [nr_generate_pucch1] block-wise spread with the orthogonal sequence wi(m) if intraSlotFrequencyHopping = %d\n", + intraSlotFrequencyHopping); + #endif + N_SF_mprime_PUCCH_1 = table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_noHop[nrofSymbols-1]; // only if intra-slot hopping not enabled (PUCCH) + N_SF_mprime_PUCCH_DMRS_1 = table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_noHop[nrofSymbols-1]; // only if intra-slot hopping not enabled (DM-RS) + N_SF_mprime0_PUCCH_1 = table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_noHop[nrofSymbols-1]; // only if intra-slot hopping not enabled mprime = 0 (PUCCH) + N_SF_mprime0_PUCCH_DMRS_1 = table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_noHop[nrofSymbols-1]; // only if intra-slot hopping not enabled mprime = 0 (DM-RS) + for (int m=0; m < N_SF_mprime_PUCCH_1; m++){ + for (int n=0; n<12 ; n++){ + z_re[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*y_n_re[n])>>15) + - (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*y_n_im[n])>>15)); + z_im[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*y_n_im[n])>>15) + + (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*y_n_re[n])>>15)); + #ifdef DEBUG_NR_PUCCH_TX + printf("\t\t z_pucch[%d] \t= ((%d \t* %d \t-%d \t* %d), (%d \t* %d \t+%d \t*%d)) = (%d,%d)\n", + (mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n, + table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],y_n_re[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],y_n_im[n], + table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],y_n_im[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],y_n_re[n], + z_re[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],z_im[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]); + #endif + } + } + for (int m=0; m < N_SF_mprime_PUCCH_DMRS_1; m++){ + for (int n=0; n<12 ; n++){ + z_dmrs_re[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_re[n])>>15) + - (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_im[n])>>15)); + z_dmrs_im[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_im[n])>>15) + + (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_re[n])>>15)); + #ifdef DEBUG_NR_PUCCH_TX + printf("\t\t z_dm-rs[%d] = ((),()) =(%d,%d)\n", + (mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n,z_dmrs_re[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],z_dmrs_im[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]); + #endif + } + } + } + if (intraSlotFrequencyHopping == 1) { // intra-slot hopping enabled + #ifdef DEBUG_NR_PUCCH_TX + printf("\t [nr_generate_pucch1] block-wise spread with the orthogonal sequence wi(m) if intraSlotFrequencyHopping = %d\n", + intraSlotFrequencyHopping); + #endif + N_SF_mprime_PUCCH_1 = table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_m0Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 0 (PUCCH) + N_SF_mprime_PUCCH_DMRS_1 = table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_m0Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 0 (DM-RS) + N_SF_mprime0_PUCCH_1 = table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_m0Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 0 (PUCCH) + N_SF_mprime0_PUCCH_DMRS_1 = table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_m0Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 0 (DM-RS) + for (mprime = 0; mprime<2; mprime++){ // mprime can get values {0,1} + for (int m=0; m < N_SF_mprime_PUCCH_1; m++){ + for (int n=0; n<12 ; n++){ + z_re[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*y_n_re[n])>>15) + - (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*y_n_im[n])>>15)); + z_im[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*y_n_im[n])>>15) + + (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*y_n_re[n])>>15)); + } + } + for (int m=0; m < N_SF_mprime_PUCCH_DMRS_1; m++){ + for (int n=0; n<12 ; n++){ + z_dmrs_re[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_re[n])>>15) + - (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_im[n])>>15)); + z_dmrs_im[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_im[n])>>15) + + (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_re[n])>>15)); + } + } + N_SF_mprime_PUCCH_1 = table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_m1Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 1 (PUCCH) + N_SF_mprime_PUCCH_DMRS_1 = table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_m1Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 1 (DM-RS) + } + } +/* + * Implementing TS 38.211 Subclause 6.3.2.4.2 Mapping to physical resources + */ + int32_t *txptr; + uint32_t re_offset; + int i=0; + for (int l=0; lN_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is lower band + re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset; + } + if ((startingPRB >= (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is upper band + re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(startingPRB-(frame_parms->N_RB_DL>>1))); + } + if ((startingPRB < (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB is lower band + re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset; + } + if ((startingPRB > (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB is upper band + re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(startingPRB-(frame_parms->N_RB_DL>>1))) + 6; + } + if ((startingPRB == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB contains DC + re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset; + } + txptr = &txdataF[0][re_offset]; + for (int n=0; n<12; n++){ + if ((n==6) && (startingPRB == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { + // if number RBs in bandwidth is odd and current PRB contains DC, we need to recalculate the offset when n=6 (for second half PRB) + re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size); + } + if (l%2 == 1) { // mapping PUCCH according to TS38.211 subclause 6.4.1.3.1 + ((int16_t *)&txdataF[0][re_offset])[0] = z_re[i+n]; + ((int16_t *)&txdataF[0][re_offset])[1] = z_im[i+n]; + #ifdef DEBUG_NR_PUCCH_TX + printf("\t [nr_generate_pucch1] mapping PUCCH to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_pucch[%d]=txptr(%d)=(x_n(l=%d,n=%d)=(%d,%d))\n", + amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,i+n,re_offset, + l,n,((int16_t *)&txdataF[0][re_offset])[0],((int16_t *)&txdataF[0][re_offset])[1]); + #endif + } + if (l%2 == 0) { // mapping DM-RS signal according to TS38.211 subclause 6.4.1.3.1 + ((int16_t *)&txdataF[0][re_offset])[0] = z_dmrs_re[i+n]; + ((int16_t *)&txdataF[0][re_offset])[1] = z_dmrs_im[i+n]; + #ifdef DEBUG_NR_PUCCH_TX + printf("\t [nr_generate_pucch1] mapping DM-RS to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_dm-rs[%d]=txptr(%d)=(x_n(l=%d,n=%d)=(%d,%d))\n", + amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,i+n,re_offset, + l,n,((int16_t *)&txdataF[0][re_offset])[0],((int16_t *)&txdataF[0][re_offset])[1]); + #endif + } + re_offset++; + } + if (l%2 == 1) i+=12; + } +} + +inline void nr_pucch2_3_4_scrambling(uint16_t M_bit,uint16_t rnti,uint16_t n_id,uint32_t B,uint8_t *btilde) __attribute__((always_inline)); +inline void nr_pucch2_3_4_scrambling(uint16_t M_bit,uint16_t rnti,uint16_t n_id,uint32_t B,uint8_t *btilde) { + + uint32_t x1, x2, s=0; + int i; + uint8_t c; + // c_init=nRNTI*2^15+n_id according to TS 38.211 Subclause 6.3.2.6.1 + //x2 = (rnti) + ((uint32_t)(1+nr_tti_rx)<<16)*(1+(fp->Nid_cell<<1)); + x2 = ((rnti)<<15)+n_id; + s = lte_gold_generic(&x1, &x2, 1); + #ifdef DEBUG_NR_PUCCH_TX + printf("\t\t [nr_pucch2_3_4_scrambling] gold sequence s=%lx\n",s); + #endif + for (i=0;i>i)&1); + btilde[i] = (((B>>i)&1) ^ c); + #ifndef DEBUG_NR_PUCCH_TX + printf("\t\t\t btilde[%d]=%lx from scrambled bit %d\n",i,btilde[i],((B>>i)&1)); + #endif + } + #ifdef DEBUG_NR_PUCCH_TX + printf("\t\t [nr_pucch2_3_4_scrambling] scrambling M_bit=%d bits\n", M_bit); + #endif + +} +void nr_uci_encoding(uint64_t payload, + uint8_t nr_bit, + pucch_format_nr_t fmt, + uint8_t is_pi_over_2_bpsk_enabled, + uint8_t nrofSymbols, + uint8_t nrofPRB, + uint8_t n_SF_PUCCH_s, + uint8_t intraSlotFrequencyHopping, + uint8_t add_dmrs, + uint64_t *b, + uint16_t *M_bit) { + /* + * Implementing TS 38.212 Subclause 6.3.1.2 + * + */ + + // A is the payload size, to be provided in function call + uint8_t A = nr_bit; + // L is the CRC size + uint8_t L; + // E is the rate matching output sequence length as given in TS 38.212 subclause 6.3.1.4.1 + uint16_t E,E_init; + if (fmt == pucch_format2_nr) E = 16*nrofSymbols*nrofPRB; + if (fmt == pucch_format3_nr){ + E_init = (is_pi_over_2_bpsk_enabled == 0) ? 24:12; + if (nrofSymbols == 4) { + E = (intraSlotFrequencyHopping == 0)?(E_init*(nrofSymbols-1)*nrofPRB):((E_init*(nrofSymbols-1)*nrofPRB)); + printf("format 3 nrofSymbols =4 and E_init=%d,E=%d\n",E_init,E); + } + if (nrofSymbols > 4) { + E = E_init*(nrofSymbols-2)*nrofPRB; + printf("format 3 nrofSymbols >4 and E_init=%d,E = %d\n",E_init,E); + } + if (nrofSymbols > 9) { + E = (add_dmrs == 0)?(E_init*(nrofSymbols-2)*nrofPRB):((E_init*(nrofSymbols-4)*nrofPRB)); + printf("format 3 nrofSymbols >9 and E_init=%d,E = %d\n",E_init,E); + } + } + if (fmt == pucch_format4_nr){ + E_init = (is_pi_over_2_bpsk_enabled == 0) ? 24:12; + if (nrofSymbols == 4) { + E = (intraSlotFrequencyHopping == 0)?(E_init*(nrofSymbols-1)/n_SF_PUCCH_s):((E_init*(nrofSymbols-1)/n_SF_PUCCH_s)); + printf("format 4 nrofSymbols =4 and E_init=%d,E=%d\n",E_init,E); + } + if (nrofSymbols > 4) { + E = E_init*(nrofSymbols-2)/n_SF_PUCCH_s; + printf("format 4 nrofSymbols >4 and E_init=%d,E = %d\n",E_init,E); + } + if (nrofSymbols > 9) { + E = (add_dmrs == 0)?(E_init*(nrofSymbols-2)/n_SF_PUCCH_s):((E_init*(nrofSymbols-4)/n_SF_PUCCH_s)); + printf("format 4 nrofSymbols >9 and E_init=%d,E = %d\n",E_init,E); + } + } + *M_bit = E; + int I_seg; + #ifdef DEBUG_NR_PUCCH_TX + printf("\t\t [nr_uci_encoding] start function with fmt=%d, encoding A=%d bits into M_bit=%d (where nrofSymbols=%d,nrofPRB=%d)\n",fmt,A,*M_bit,nrofSymbols,nrofPRB); + #endif + + if (A<=11){ + // procedure in subclause 6.3.1.2.2 (UCI encoded by channel coding of small block lengths -> subclause 6.3.1.3.2) + // CRC bits are not attached, and coding small block lengths (subclause 5.3.3) + } else if (A>=12){ + // procedure in subclause 6.3.1.2.1 (UCI encoded by Polar code -> subclause 6.3.1.3.1) + if ((A>=360 && E>=1088)||(A>=1013)){ + I_seg = 1; + } else { + I_seg = 0; + } + if (A>=20){ + // parity bits (subclause 5.2.1) computed by setting L=11 and using generator polynomial gCRC11(D) (subclause 5.1) + L=11; + } else if (A<=19){ + // parity bits (subclause 5.2.1) computed by setting L=6 and using generator polynomial gCRC6(D) (subclause 5.1) + L=6; + } + // code block segmentation and CRC attachment is performed according to subclause 5.2.1 + // polar coding subclause 5.3.1 + } +} +//#if 0 +void nr_generate_pucch2(int32_t **txdataF, + NR_DL_FRAME_PARMS *frame_parms, + PUCCH_CONFIG_DEDICATED *pucch_config_dedicated, + uint64_t payload, + int16_t amp, + uint8_t nr_tti_rx, + uint8_t nrofSymbols, + uint8_t startingSymbolIndex, + uint8_t nrofPRB, + uint8_t startingPRB, + uint8_t nr_bit) { + #ifdef DEBUG_NR_PUCCH_TX + printf("\t [nr_generate_pucch2] start function with payload=%d and nr_bit=%d\n", payload, nr_bit); + #endif + // b is the block of bits transmitted on the physical channel after payload coding + uint64_t b; + // M_bit is the number of bits of block b (payload after encoding) + uint16_t M_bit; + nr_uci_encoding(payload,nr_bit,pucch_format2_nr,0,nrofSymbols,nrofPRB,1,0,0,&b,&M_bit); + + /* + * Implementing TS 38.211 + * Subclauses 6.3.2.5.1 Scrambling (PUCCH format 2) + * The block of bits b(0),..., b(M_bit-1 ), where M_bit is the number of bits transmitted on the physical channel, + * shall be scrambled prior to modulation, + * resulting in a block of scrambled bits btilde(0),...,btilde(M_bit-1) according to + * btilde(i)=(b(i)+c(i))mod 2 + * where the scrambling sequence c(i) is given by clause 5.2.1. + * The scrambling sequence generator shall be initialized with c_init=nRNTI*2^15+n_id + * n_id = {0,1,...,1023} equals the higher-layer parameter Data-scrambling-Identity if configured + * n_id = N_ID_cell if higher layer parameter not configured + */ + + uint8_t *btilde = malloc(sizeof(int8_t)*M_bit); + uint16_t rnti=0xff, n_id=0; + + /* + * Implementing TS 38.211 Subclause 6.3.2.5.1 scrambling format 2 + */ + nr_pucch2_3_4_scrambling(M_bit,rnti,n_id,b,btilde); + + /* + * Implementing TS 38.211 Subclause 6.3.2.5.2 modulation format 2 + * btilde shall be modulated as described in subclause 5.1 using QPSK + * resulting in a block of complex-valued modulation symbols d(0),...,d(m_symbol) where m_symbol=M_bit/2 + */ + +//#define ONE_OVER_SQRT2_S 23171 // 32767/sqrt(2) = 23170 (ONE_OVER_SQRT2) + + // complex-valued symbol d(0) + int16_t *d_re = malloc(sizeof(int16_t)*M_bit); + int16_t *d_im = malloc(sizeof(int16_t)*M_bit); + uint16_t m_symbol = (M_bit%2==0) ? M_bit/2 : floor(M_bit/2)+1; + for (int i=0; i < m_symbol; i++){ // QPSK modulation subclause 5.1.3 + if (((btilde[2*i]&1)==0) && ((btilde[(2*i)+1]&1)==0)) { + d_re[i] = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); + d_im[i] = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); + } + if (((btilde[2*i]&1)==0) && ((btilde[(2*i)+1]&1)==1)) { + d_re[i] = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); + d_im[i] = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); + } + if (((btilde[2*i]&1)==1) && ((btilde[(2*i)+1]&1)==0)) { + d_re[i] = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); + d_im[i] = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); + } + if (((btilde[2*i]&1)==1) && ((btilde[(2*i)+1]&1)==1)) { + d_re[i] = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); + d_im[i] = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); + } + #ifdef DEBUG_NR_PUCCH_TX + printf("\t [nr_generate_pucch2] modulation of bit pair btilde(%d,%d), m_symbol=%d, d(%d)=(%d,%d)\n",(btilde[2*i]&1),(btilde[(2*i)+1]&1),m_symbol,i,d_re[i],d_im[i]); + #endif + } + + + /* + * Implementing TS 38.211 Subclause 6.3.2.5.3 Mapping to physical resources + */ + int32_t *txptr; + uint32_t re_offset; + uint32_t x1, x2, s=0; + int i=0; + int m=0; + for (int l=0; lN_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is lower band + re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(rb+startingPRB)) + frame_parms->first_carrier_offset; + } + if (((rb+startingPRB) >= (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is upper band + re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*((rb+startingPRB)-(frame_parms->N_RB_DL>>1))); + } + if (((rb+startingPRB) < (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB is lower band + re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(rb+startingPRB)) + frame_parms->first_carrier_offset; + } + if (((rb+startingPRB) > (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB is upper band + re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*((rb+startingPRB)-(frame_parms->N_RB_DL>>1))) + 6; + } + if (((rb+startingPRB) == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB contains DC + re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(rb+startingPRB)) + frame_parms->first_carrier_offset; + } + txptr = &txdataF[0][re_offset]; + int k=0; + int kk=0; + for (int n=0; n<12; n++){ + if ((n==6) && ((rb+startingPRB) == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { + // if number RBs in bandwidth is odd and current PRB contains DC, we need to recalculate the offset when n=6 (for second half PRB) + re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size); + } + if (n%3 != 1) { // mapping PUCCH according to TS38.211 subclause 6.3.2.5.3 + ((int16_t *)&txdataF[0][re_offset])[0] = d_re[i+k]; + ((int16_t *)&txdataF[0][re_offset])[1] = d_im[i+k]; + #ifdef DEBUG_NR_PUCCH_TX + printf("\t [nr_generate_pucch1] (n=%d,i=%d) mapping PUCCH to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_pucch[%d]=txptr(%d)=(x_n(l=%d,n=%d)=(%d,%d))\n", + n,i,amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,i+k,re_offset, + l,n,((int16_t *)&txdataF[0][re_offset])[0],((int16_t *)&txdataF[0][re_offset])[1]); + #endif + k++; + } + if (n%3 == 1) { // mapping DM-RS signal according to TS38.211 subclause 6.4.1.3.2 + ((int16_t *)&txdataF[0][re_offset])[0] = (int16_t)((int32_t)(amp*ONE_OVER_SQRT2*(1-(2*((uint8_t)((s>>(2*m))&1)))))>>15); + ((int16_t *)&txdataF[0][re_offset])[1] = (int16_t)((int32_t)(amp*ONE_OVER_SQRT2*(1-(2*((uint8_t)((s>>((2*m)+1))&1)))))>>15); + m++; + #ifdef DEBUG_NR_PUCCH_TX + printf("\t [nr_generate_pucch1] (n=%d,i=%d) mapping DM-RS to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_dm-rs[%d]=txptr(%d)=(x_n(l=%d,n=%d)=(%d,%d))\n", + n,i,amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,i+kk,re_offset, + l,n,((int16_t *)&txdataF[0][re_offset])[0],((int16_t *)&txdataF[0][re_offset])[1]); + #endif + kk++; + } + re_offset++; + } + i+=8; + } + } +} +//#if 0 +void nr_generate_pucch3_4(int32_t **txdataF, + NR_DL_FRAME_PARMS *frame_parms, + pucch_format_nr_t fmt, + PUCCH_CONFIG_DEDICATED *pucch_config_dedicated, + uint64_t payload, + int16_t amp, + uint8_t nr_tti_rx, + uint8_t nrofSymbols, + uint8_t startingSymbolIndex, + uint8_t nrofPRB, + uint8_t startingPRB, + uint8_t nr_bit, + uint8_t occ_length_format4, + uint8_t occ_index_format4) { + + #ifdef DEBUG_NR_PUCCH_TX + printf("\t [nr_generate_pucch3_4] start function with payload=%d and nr_bit=%d\n", payload, nr_bit); + #endif + // b is the block of bits transmitted on the physical channel after payload coding + uint64_t b; + // M_bit is the number of bits of block b (payload after encoding) + uint16_t M_bit; + // parameter PUCCH-F4-preDFT-OCC-length set of {2,4} -> to use table -1 or -2 + uint8_t n_SF_PUCCH_s = 2; // in format 4, n_SF_PUCCH_s = {2,4}, provided by higher layer parameter PUCCH-F4-preDFT-OCC-length (in format 3 n_SF_PUCCH_s=1), FIXME!!! + uint8_t is_pi_over_2_bpsk_enabled = 0; // this value has to be provided by higher layers parameter + // Intra-slot frequency hopping shall be assumed when the higher-layer parameter intraSlotFrequencyHopping is provided, + // regardless of whether the frequency-hop distance is zero or not, + // otherwise no intra-slot frequency hopping shall be assumed + //uint8_t PUCCH_Frequency_Hopping = 0 ; // from higher layers. Let's suppose we do not support intra-slot hopping FIXME!! + uint8_t intraSlotFrequencyHopping = 0; + // add_dmrs indicates if we are using or not Additional DM-RS for formats 3 and 4. From higher layers. FIXME!!! + uint8_t add_dmrs = 0; + nr_uci_encoding(payload,nr_bit,fmt,is_pi_over_2_bpsk_enabled,nrofSymbols,nrofPRB,n_SF_PUCCH_s,intraSlotFrequencyHopping,add_dmrs,&b,&M_bit); + + /* + * Implementing TS 38.211 + * Subclauses 6.3.2.6.1 Scrambling (PUCCH formats 3 and 4) + * The block of bits b(0),..., b(M_bit-1 ), where M_bit is the number of bits transmitted on the physical channel, + * shall be scrambled prior to modulation, + * resulting in a block of scrambled bits btilde(0),...,btilde(M_bit-1) according to + * btilde(i)=(b(i)+c(i))mod 2 + * where the scrambling sequence c(i) is given by clause 5.2.1. + * The scrambling sequence generator shall be initialized with c_init=nRNTI*2^15+n_id + * n_id = {0,1,...,1023} equals the higher-layer parameter Data-scrambling-Identity if configured + * n_id = N_ID_cell if higher layer parameter not configured + */ + + uint8_t *btilde = malloc(sizeof(int8_t)*M_bit); + uint16_t rnti=0xff, n_id=0; + + /* + * Implementing TS 38.211 Subclause 6.3.2.6.1 scrambling formats 3 and 4 + */ + nr_pucch2_3_4_scrambling(M_bit,rnti,n_id,b,btilde); + + /* + * Implementing TS 38.211 Subclause 6.3.2.6.2 modulation formats 3 and 4 + * + * Subclause 5.1.1 PI/2-BPSK + * Subclause 5.1.3 QPSK + */ + // complex-valued symbol d(0) + int16_t *d_re = malloc(sizeof(int16_t)*M_bit); + int16_t *d_im = malloc(sizeof(int16_t)*M_bit); + uint16_t m_symbol = (M_bit%2==0) ? M_bit/2 : floor(M_bit/2)+1; + if (is_pi_over_2_bpsk_enabled == 0){ + // using QPSK if PUCCH format 3,4 and pi/2-BPSK is not configured, according to subclause 6.3.2.6.2 + for (int i=0; i < m_symbol; i++){ // QPSK modulation subclause 5.1.3 + if (((btilde[2*i]&1)==0) && ((btilde[(2*i)+1]&1)==0)) { + d_re[i] = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); + d_im[i] = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); + } + if (((btilde[2*i]&1)==0) && ((btilde[(2*i)+1]&1)==1)) { + d_re[i] = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); + d_im[i] = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); + } + if (((btilde[2*i]&1)==1) && ((btilde[(2*i)+1]&1)==0)) { + d_re[i] = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); + d_im[i] = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); + } + if (((btilde[2*i]&1)==1) && ((btilde[(2*i)+1]&1)==1)) { + d_re[i] = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); + d_im[i] = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); + } + #ifdef DEBUG_NR_PUCCH_TX + printf("\t [nr_generate_pucch3_4] modulation QPSK of bit pair btilde(%d,%d), m_symbol=%d, d(%d)=(%d,%d)\n",(btilde[2*i]&1),(btilde[(2*i)+1]&1),m_symbol,i,d_re[i],d_im[i]); + #endif + } + } + if (is_pi_over_2_bpsk_enabled == 1){ + // using PI/2-BPSK if PUCCH format 3,4 and pi/2-BPSK is configured, according to subclause 6.3.2.6.2 + m_symbol = M_bit; + for (int i=0; i>15); + d_im[i] = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); + } + if (((btilde[i]&1)==0) && (i%2 == 1)){ + d_re[i] = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); + d_im[i] = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); + } + if (((btilde[i]&1)==1) && (i%2 == 0)){ + d_re[i] = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); + d_im[i] = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); + } + if (((btilde[i]&1)==1) && (i%2 == 1)){ + d_re[i] = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); + d_im[i] = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); + } + #ifdef DEBUG_NR_PUCCH_TX + printf("\t [nr_generate_pucch3_4] modulation PI/2-BPSK of bit btilde(%d), m_symbol=%d, d(%d)=(%d,%d)\n",(btilde[i]&1),m_symbol,i,d_re[i],d_im[i]); + #endif + } + } + + /* + * Implementing Block-wise spreading subclause 6.3.2.6.3 + */ + // number of PRBs per PUCCH, provided by higher layers parameters PUCCH-F2-number-of-PRBs or PUCCH-F3-number-of-PRBs (for format 4, it is equal to 1) + // for PUCCH 3 -> nrofPRBs = (2^alpa2 * 3^alpha3 * 5^alpha5) + // for PUCCH 4 -> nrofPRBs = 1 + // uint8_t nrofPRBs; + // number of symbols, provided by higher layers parameters PUCCH-F0-F2-number-of-symbols or PUCCH-F1-F3-F4-number-of-symbols + // uint8_t nrofSymbols; + // complex-valued symbol d(0) + int16_t *y_n_re = malloc(sizeof(int16_t)*4*M_bit); // 4 is the maximum number n_SF_PUCCH_s, so is the maximunm size of y_n + int16_t *y_n_im = malloc(sizeof(int16_t)*4*M_bit); + // Re part orthogonal sequences w_n(k) for PUCCH format 4 when N_SF_PUCCH4 = 2 (Table 6.3.2.6.3-1) + // k={0,..11} n={0,1,2,3} + // parameter PUCCH-F4-preDFT-OCC-index set of {0,1,2,3} -> n + uint16_t table_6_3_2_6_3_1_Wi_Re[2][12] = {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, + {1, 1, 1, 1, 1, 1,-1,-1,-1,-1,-1,-1}}; + // Im part orthogonal sequences w_n(k) for PUCCH format 4 when N_SF_PUCCH4 = 2 (Table 6.3.2.6.3-1) + // k={0,..11} n={0,1} + uint16_t table_6_3_2_6_3_1_Wi_Im[2][12] = {{0,0,0,0,0,0,0,0,0,0,0,0}, + {0,0,0,0,0,0,0,0,0,0,0,0}}; + // Re part orthogonal sequences w_n(k) for PUCCH format 4 when N_SF_PUCCH4 = 4 (Table 6.3.2.6.3-2) + // k={0,..11} n={0,1,2.3} + uint16_t table_6_3_2_6_3_2_Wi_Re[4][12] = {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, + {1, 1, 1, 0, 0, 0,-1,-1,-1, 0, 0, 0}, + {1, 1, 1,-1,-1,-1, 1, 1, 1,-1,-1,-1}, + {1, 1, 1, 0, 0, 0,-1,-1,-1, 0, 0, 0}}; + // Im part orthogonal sequences w_n(k) for PUCCH format 4 when N_SF_PUCCH4 = 4 (Table 6.3.2.6.3-2) + // k={0,..11} n={0,1,2,3} + uint16_t table_6_3_2_6_3_2_Wi_Im[4][12] = {{0,0,0, 0, 0, 0,0,0,0, 0, 0, 0}, + {0,0,0,-1,-1,-1,0,0,0, 1, 1, 1}, + {0,0,0, 0, 0, 0,0,0,0, 0, 0, 0}, + {0,0,0, 1, 1, 1,0,0,0,-1,-1,-1}}; + uint8_t occ_Length = occ_length_format4; // higher layer parameter occ-Length + uint8_t occ_Index = occ_index_format4; // higher layer parameter occ-Index + + if (fmt == pucch_format3_nr){ // no block-wise spreading for format 3 + n_SF_PUCCH_s = 1; + for (int l=0; l < floor(m_symbol/(12*nrofPRB)); l++){ + for (int k=0; k < (12*nrofPRB); k++){ + y_n_re[l*(12*nrofPRB)+k] = d_re[l*(12*nrofPRB)+k]; + y_n_im[l*(12*nrofPRB)+k] = d_im[l*(12*nrofPRB)+k]; + #ifdef DEBUG_NR_PUCCH_TX + printf("\t [nr_generate_pucch3_4] block-wise spreading for format 3 (no block-wise spreading): (l,k)=(%d,%d)\ty_n(%d) = \t(d_re=%d, d_im=%d)\n", + l,k,l*(12*nrofPRB)+k,d_re[l*(12*nrofPRB)+k],d_im[l*(12*nrofPRB)+k]); + #endif + } + } + } + if (fmt == pucch_format4_nr){ + nrofPRB = 1; + for (int l=0; l < floor((n_SF_PUCCH_s*m_symbol)/(12*nrofPRB)); l++){ + for (int k=0; k < (12*nrofPRB); k++){ + if (n_SF_PUCCH_s == 2){ + y_n_re[l*(12*nrofPRB)+k] = (uint16_t)(((uint32_t)d_re[l*(12*nrofPRB/n_SF_PUCCH_s)+k%(12*nrofPRB/n_SF_PUCCH_s)] * table_6_3_2_6_3_1_Wi_Re[occ_Index][k]) + - ((uint32_t)d_im[l*(12*nrofPRB/n_SF_PUCCH_s)+k%(12*nrofPRB/n_SF_PUCCH_s)] * table_6_3_2_6_3_1_Wi_Im[occ_Index][k])); + y_n_im[l*(12*nrofPRB)+k] = (uint16_t)(((uint32_t)d_im[l*(12*nrofPRB/n_SF_PUCCH_s)+k%(12*nrofPRB/n_SF_PUCCH_s)] * table_6_3_2_6_3_1_Wi_Re[occ_Index][k]) + + ((uint32_t)d_re[l*(12*nrofPRB/n_SF_PUCCH_s)+k%(12*nrofPRB/n_SF_PUCCH_s)] * table_6_3_2_6_3_1_Wi_Im[occ_Index][k])); + #ifdef DEBUG_NR_PUCCH_TX + printf("\t [nr_generate_pucch3_4] block-wise spreading for format 4 (n_SF_PUCCH_s 2): (l,k)=(%d,%d)\ty_n(%d) = \t(d_re=%d, d_im=%d)\n", + l,k,l*(12*nrofPRB)+k,y_n_re[l*(12*nrofPRB)+k],y_n_im[l*(12*nrofPRB)+k]); + #endif + } + if (n_SF_PUCCH_s == 4){ + y_n_re[l*(12*nrofPRB)+k] = (uint16_t)(((uint32_t)d_re[l*(12*nrofPRB/n_SF_PUCCH_s)+k%(12*nrofPRB/n_SF_PUCCH_s)] * table_6_3_2_6_3_2_Wi_Re[occ_Index][k]) + - ((uint32_t)d_im[l*(12*nrofPRB/n_SF_PUCCH_s)+k%(12*nrofPRB/n_SF_PUCCH_s)] * table_6_3_2_6_3_2_Wi_Im[occ_Index][k])); + y_n_im[l*(12*nrofPRB)+k] = (uint16_t)(((uint32_t)d_im[l*(12*nrofPRB/n_SF_PUCCH_s)+k%(12*nrofPRB/n_SF_PUCCH_s)] * table_6_3_2_6_3_2_Wi_Re[occ_Index][k]) + + ((uint32_t)d_re[l*(12*nrofPRB/n_SF_PUCCH_s)+k%(12*nrofPRB/n_SF_PUCCH_s)] * table_6_3_2_6_3_2_Wi_Im[occ_Index][k])); + #ifdef DEBUG_NR_PUCCH_TX + printf("\t [nr_generate_pucch3_4] block-wise spreading for format 4 (n_SF_PUCCH_s 4): (l,k)=(%d,%d)\ty_n(%d) = \t(d_re=%d, d_im=%d)\n", + l,k,l*(12*nrofPRB)+k,y_n_re[l*(12*nrofPRB)+k],y_n_im[l*(12*nrofPRB)+k]); + #endif + } + } + } + } + + /* + * Implementing Transform pre-coding subclause 6.3.2.6.4 + */ + int16_t *z_re = malloc(sizeof(int16_t)*4*M_bit); // 4 is the maximum number n_SF_PUCCH_s + int16_t *z_im = malloc(sizeof(int16_t)*4*M_bit); + # define M_PI 3.14159265358979323846 // pi + //int16_t inv_sqrt_nrofPRBs = (int16_t)round(32767/sqrt(12*nrofPRB)); + for (int l=0; l>15) + + (((int32_t)y_n_im[l*(12*nrofPRB)+m] * (int16_t)round(32767 * sin(2*M_PI*m*k/(12*nrofPRB))))>>15)))>>15); + z_im[l*(12*nrofPRB)+k] = z_im[l*(12*nrofPRB)+k] + + (int16_t)(((int32_t)round(32767/sqrt(12*nrofPRB))*(int16_t)((((int32_t)y_n_im[l*(12*nrofPRB)+m] * (int16_t)round(32767 * cos(2*M_PI*m*k/(12*nrofPRB))))>>15) + - (((int32_t)y_n_re[l*(12*nrofPRB)+m] * (int16_t)round(32767 * sin(2*M_PI*m*k/(12*nrofPRB))))>>15)))>>15); + #ifndef DEBUG_NR_PUCCH_TX + printf("\t [nr_generate_pucch3_4] transform precoding for formats 3 and 4: (l,k,m)=(%d,%d,%d)\tz(%d) = \t(%d, %d)\n", + l,k,m,l*(12*nrofPRB)+k,z_re[l*(12*nrofPRB)+k],z_im[l*(12*nrofPRB)+k]); + #endif + } + #ifdef DEBUG_NR_PUCCH_TX + printf("\t\t\t [nr_generate_pucch3_4] transform precoding for formats 3 and 4: (l,k)=(%d,%d)\tz(%d) = \t(%d, %d)\n", + l,k,l*(12*nrofPRB)+k,z_re[l*(12*nrofPRB)+k],z_im[l*(12*nrofPRB)+k]); + #endif + } + } + + /* + * Implementing TS 38.211 Subclauses 6.3.2.5.3 and 6.3.2.6.5 Mapping to physical resources FIXME! + */ + // the value of u,v (delta always 0 for PUCCH) has to be calculated according to TS 38.211 Subclause 6.3.2.2.1 + uint8_t u=0,v=0,delta=0; + // depending on the value of the PUCCH_GroupHopping, we will obtain different values for u,v + uint8_t PUCCH_GroupHopping; // from higher layers FIXME!! + // if frequency hopping is disabled, intraSlotFrequencyHopping is not provided + // n_hop = 0 + // if frequency hopping is enabled, intraSlotFrequencyHopping is provided + // n_hop = 0 for first hop + // n_hop = 1 for second hop + uint8_t n_hop = 0; + // lnormal is the OFDM symbol number in the PUCCH transmission where l=0 corresponds to the first OFDM symbol of the PUCCH transmission + uint8_t lnormal = 0 ; + // lprime is the index of the OFDM symbol in the slot that corresponds to the first OFDM symbol of the PUCCH transmission in the slot given by [5, TS 38.213] + uint8_t lprime = startingSymbolIndex; + // m0 is the cyclic shift index calculated depending on the Orthogonal sequence index n, according to table 6.4.1.3.3.1-1 from TS 38.211 subclause 6.4.1.3.3.1 + uint8_t m0; + uint8_t mcs=0; + if (fmt == pucch_format3_nr) m0 = 0; + if (fmt == pucch_format4_nr) { + if (n_SF_PUCCH_s == 2) { + m0 = (occ_Index == 0) ? 0 : 6; + } + if (n_SF_PUCCH_s == 4) { + m0 = (occ_Index == 3) ? 9 : ((occ_Index == 2) ? 3 : ((occ_Index == 1) ? 6 : 0)); + } + } + double alpha; + uint8_t N_ZC = 12*nrofPRB; + int16_t *r_u_v_base_re = malloc(sizeof(int16_t)*12*nrofPRB); + int16_t *r_u_v_base_im = malloc(sizeof(int16_t)*12*nrofPRB); + int16_t *r_u_v_alpha_delta_re = malloc(sizeof(int16_t)*12*nrofPRB); + int16_t *r_u_v_alpha_delta_im = malloc(sizeof(int16_t)*12*nrofPRB); + nr_group_sequence_hopping(PUCCH_GroupHopping,n_id,n_hop,nr_tti_rx,&u,&v); // calculating u and v value + // Next we proceed to calculate base sequence for DM-RS signal, according to TS 38.211 subclause 6.4.1.33 + if (nrofPRB >= 3) { // TS 38.211 subclause 5.2.2.1 (Base sequences of length 36 or larger) applies + uint8_t list_of_prime_numbers[46] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, + 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, + 73, 79, 83, 89, 97, 101,103,107,109,113, + 127,131,137,139,149,151,157,163,167,173, + 179,181,191,193,197,199}; + int i = 4; + while (list_of_prime_numbers[i] < (12*nrofPRB)) i++; + N_ZC = list_of_prime_numbers[i+1]; // N_ZC is given by the largest prime number such that N_ZC < (12*nrofPRB) + double q_base = (N_ZC*(u+1))/31; + int8_t q = (uint8_t)floor(q_base + (1/2)); + q = ((uint8_t)floor(2*q_base)%2 == 0 ? q+v : q-v); + for (int n=0; n<(12*nrofPRB); n++){ + r_u_v_base_re[n] = (int16_t)(((int32_t)amp*(int16_t)(32767*cos(M_PI*q*(n%N_ZC)*((n%N_ZC)+1)/N_ZC)))>>15); + r_u_v_base_im[n] = -(int16_t)(((int32_t)amp*(int16_t)(32767*sin(M_PI*q*(n%N_ZC)*((n%N_ZC)+1)/N_ZC)))>>15); + #ifdef DEBUG_NR_PUCCH_TX + printf("\t [nr_generate_pucch3_4] generation DM-RS base sequence when nrofPRB=%d >= 3: r_u_v_base[n=%d]=(%d,%d)\n", + nrofPRB,n,r_u_v_base_re[n],r_u_v_base_im[n]); + #endif + } + } + if (nrofPRB == 2) { // TS 38.211 subclause 5.2.2.2 (Base sequences of length less than 36 using table 5.2.2.2-4) applies + for (int n=0; n<(12*nrofPRB); n++){ + r_u_v_base_re[n] = (int16_t)(((int32_t)amp*table_5_2_2_2_4_Re[u][n])>>15); + r_u_v_base_im[n] = (int16_t)(((int32_t)amp*table_5_2_2_2_4_Im[u][n])>>15); + #ifdef DEBUG_NR_PUCCH_TX + printf("\t [nr_generate_pucch3_4] generation DM-RS base sequence when nrofPRB=%d == 2: r_u_v_base[n=%d]=(%d,%d)\n", + nrofPRB,n,r_u_v_base_re[n],r_u_v_base_im[n]); + #endif + } + } + if (nrofPRB == 1) { // TS 38.211 subclause 5.2.2.2 (Base sequences of length less than 36 using table 5.2.2.2-2) applies + for (int n=0; n<(12*nrofPRB); n++){ + r_u_v_base_re[n] = (int16_t)(((int32_t)amp*table_5_2_2_2_2_Re[u][n])>>15); + r_u_v_base_im[n] = (int16_t)(((int32_t)amp*table_5_2_2_2_2_Im[u][n])>>15); + #ifdef DEBUG_NR_PUCCH_TX + printf("\t [nr_generate_pucch3_4] generation DM-RS base sequence when nrofPRB=%d == 1: r_u_v_base[n=%d]=(%d,%d)\n", + nrofPRB,n,r_u_v_base_re[n],r_u_v_base_im[n]); + #endif + } + } + // Next we proceed to mapping to physical resources according to TS 38.211, subclause 6.3.2.6.5 dor PUCCH formats 3 and 4 and subclause 6.4.1.3.3.2 for DM-RS + int32_t *txptr; + uint32_t re_offset; + uint32_t x1, x2, s=0; + // intraSlotFrequencyHopping + // uint8_t intraSlotFrequencyHopping = 0; + uint8_t table_6_4_1_3_3_2_1_dmrs_positions[11][14] ={ + {(intraSlotFrequencyHopping==0)?0:1,(intraSlotFrequencyHopping==0)?1:0,(intraSlotFrequencyHopping==0)?0:1,0,0,0,0,0,0,0,0,0,0,0}, // PUCCH length = 4 + {1,0,0,1,0,0,0,0,0,0,0,0,0,0}, // PUCCH length = 5 + {0,1,0,0,1,0,0,0,0,0,0,0,0,0}, // PUCCH length = 6 + {0,1,0,0,1,0,0,0,0,0,0,0,0,0}, // PUCCH length = 7 + {0,1,0,0,0,1,0,0,0,0,0,0,0,0}, // PUCCH length = 8 + {0,1,0,0,0,0,1,0,0,0,0,0,0,0}, // PUCCH length = 9 + {0,(add_dmrs==0?0:1),(add_dmrs==0?1:0),(add_dmrs==0?0:1),0,0,(add_dmrs==0?0:1),(add_dmrs==0?1:0),(add_dmrs==0?0:1),0,0,0,0,0}, // PUCCH length = 10 + {0,(add_dmrs==0?0:1),(add_dmrs==0?1:0),(add_dmrs==0?0:1),0,0,(add_dmrs==0?0:1),(add_dmrs==0?1:0),0,(add_dmrs==0?0:1),0,0,0,0}, // PUCCH length = 11 + {0,(add_dmrs==0?0:1),(add_dmrs==0?1:0),0,(add_dmrs==0?0:1),0,0,(add_dmrs==0?0:1),(add_dmrs==0?1:0),0,(add_dmrs==0?0:1),0,0,0}, // PUCCH length = 12 + {0,(add_dmrs==0?0:1),(add_dmrs==0?1:0),0,(add_dmrs==0?0:1),0,0,(add_dmrs==0?0:1),0,(add_dmrs==0?1:0),0,(add_dmrs==0?0:1),0,0}, // PUCCH length = 13 + {0,(add_dmrs==0?0:1),0,(add_dmrs==0?1:0),0,(add_dmrs==0?0:1),0,0,(add_dmrs==0?0:1),0,(add_dmrs==0?1:0),0,(add_dmrs==0?0:1),0} // PUCCH length = 14 + }; + uint16_t k=0; + for (int l=0; lN_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is lower band + re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(rb+startingPRB)) + frame_parms->first_carrier_offset; + printf("1 "); + } + if (((rb+startingPRB) >= (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is upper band + re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*((rb+startingPRB)-(frame_parms->N_RB_DL>>1))); + printf("2 "); + } + if (((rb+startingPRB) < (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB is lower band + re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(rb+startingPRB)) + frame_parms->first_carrier_offset; + printf("3 "); + } + if (((rb+startingPRB) > (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB is upper band + re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*((rb+startingPRB)-(frame_parms->N_RB_DL>>1))) + 6; + printf("4 "); + } + if (((rb+startingPRB) == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB contains DC + re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(rb+startingPRB)) + frame_parms->first_carrier_offset; + printf("5 "); + } + printf("re_offset=%d,(rb+startingPRB)=%d\n",re_offset,(rb+startingPRB)); + txptr = &txdataF[0][re_offset]; + for (int n=0; n<12; n++){ + if ((n==6) && ((rb+startingPRB) == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { + // if number RBs in bandwidth is odd and current PRB contains DC, we need to recalculate the offset when n=6 (for second half PRB) + re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size); + } + if (table_6_4_1_3_3_2_1_dmrs_positions[nrofSymbols-4][l] == 0) { // mapping PUCCH according to TS38.211 subclause 6.3.2.5.3 + ((int16_t *)&txdataF[0][re_offset])[0] = z_re[n+k]; + ((int16_t *)&txdataF[0][re_offset])[1] = z_im[n+k]; + #ifdef DEBUG_NR_PUCCH_TX + printf("\t [nr_generate_pucch3_4] (l=%d,rb=%d,n=%d,k=%d) mapping PUCCH to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_pucch[%d]=txptr(%d)=(z(l=%d,n=%d)=(%d,%d))\n", + l,rb,n,k,amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,n+k,re_offset, + l,n,((int16_t *)&txdataF[0][re_offset])[0],((int16_t *)&txdataF[0][re_offset])[1]); + #endif + } + if (table_6_4_1_3_3_2_1_dmrs_positions[nrofSymbols-4][l] == 1) { // mapping DM-RS signal according to TS38.211 subclause 6.4.1.3.2 + ((int16_t *)&txdataF[0][re_offset])[0] = (int16_t)((((int32_t)(32767*cos(alpha*((n+j)%N_ZC)))*r_u_v_base_re[n+j])>>15) + - (((int32_t)(32767*sin(alpha*((n+j)%N_ZC)))*r_u_v_base_im[n+j])>>15)); + ((int16_t *)&txdataF[0][re_offset])[1] = (int16_t)((((int32_t)(32767*cos(alpha*((n+j)%N_ZC)))*r_u_v_base_im[n+j])>>15) + + (((int32_t)(32767*sin(alpha*((n+j)%N_ZC)))*r_u_v_base_re[n+j])>>15)); + #ifdef DEBUG_NR_PUCCH_TX + printf("\t [nr_generate_pucch3_4] (l=%d,rb=%d,n=%d,j=%d) mapping DM-RS to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_dm-rs[%d]=txptr(%d)=(r_u_v(l=%d,n=%d)=(%d,%d)) \t\t debug1=%d,debug2=%d,debug3=%d,debug4=%d\n", + l,rb,n,j,amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,n+j,re_offset, + l,n,((int16_t *)&txdataF[0][re_offset])[0],((int16_t *)&txdataF[0][re_offset])[1], + (((int32_t)(32767*cos(alpha*((n+j)%N_ZC)))*r_u_v_base_re[n+j])>>15), + (((int32_t)(32767*sin(alpha*((n+j)%N_ZC)))*r_u_v_base_im[n+j])>>15), + (((int32_t)(32767*cos(alpha*((n+j)%N_ZC)))*r_u_v_base_im[n+j])>>15), + (((int32_t)(32767*sin(alpha*((n+j)%N_ZC)))*r_u_v_base_re[n+j])>>15)); + #endif + } + re_offset++; + } + if (table_6_4_1_3_3_2_1_dmrs_positions[nrofSymbols-4][l] == 0) k+=12; + if (table_6_4_1_3_3_2_1_dmrs_positions[nrofSymbols-4][l] == 1) j+=12; + } + } + +} +