Commit ee1c5cbd authored by Raymond Knopp's avatar Raymond Knopp

pdcch channel estimation in UE is ok (273 PRBs)

parent e7c63993
...@@ -159,6 +159,8 @@ int nr_init_frame_parms0(NR_DL_FRAME_PARMS *fp, ...@@ -159,6 +159,8 @@ int nr_init_frame_parms0(NR_DL_FRAME_PARMS *fp,
fp->symbols_per_slot = ((Ncp == NORMAL)? 14 : 12); // to redefine for different slot formats fp->symbols_per_slot = ((Ncp == NORMAL)? 14 : 12); // to redefine for different slot formats
fp->samples_per_subframe_wCP = fp->ofdm_symbol_size * fp->symbols_per_slot * fp->slots_per_subframe; fp->samples_per_subframe_wCP = fp->ofdm_symbol_size * fp->symbols_per_slot * fp->slots_per_subframe;
fp->samples_per_frame_wCP = 10 * fp->samples_per_subframe_wCP; fp->samples_per_frame_wCP = 10 * fp->samples_per_subframe_wCP;
fp->samples_per_slot_wCP = fp->symbols_per_slot*fp->ofdm_symbol_size;
fp->samples_per_slot = fp->nb_prefix_samples0 + ((fp->symbols_per_slot-1)*fp->nb_prefix_samples) + (fp->symbols_per_slot*fp->ofdm_symbol_size);
fp->samples_per_subframe = (fp->samples_per_subframe_wCP + (fp->nb_prefix_samples0 * fp->slots_per_subframe) + fp->samples_per_subframe = (fp->samples_per_subframe_wCP + (fp->nb_prefix_samples0 * fp->slots_per_subframe) +
(fp->nb_prefix_samples * fp->slots_per_subframe * (fp->symbols_per_slot - 1))); (fp->nb_prefix_samples * fp->slots_per_subframe * (fp->symbols_per_slot - 1)));
fp->samples_per_frame = 10 * fp->samples_per_subframe; fp->samples_per_frame = 10 * fp->samples_per_subframe;
......
...@@ -25,10 +25,15 @@ ...@@ -25,10 +25,15 @@
#include "PHY/LTE_ESTIMATION/lte_estimation.h" #include "PHY/LTE_ESTIMATION/lte_estimation.h"
#include "PHY/NR_UE_ESTIMATION/nr_estimation.h" #include "PHY/NR_UE_ESTIMATION/nr_estimation.h"
//#define DEBUG_FEP #define DEBUG_FEP
#define SOFFSET 0 #define SOFFSET 0
#ifdef LOG_I
#undef LOG_I
#define LOG_I(A,B...) printf(A)
#endif
int nr_slot_fep(PHY_VARS_NR_UE *ue, int nr_slot_fep(PHY_VARS_NR_UE *ue,
unsigned char l, unsigned char l,
unsigned char Ns, unsigned char Ns,
...@@ -49,8 +54,8 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, ...@@ -49,8 +54,8 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
//int i; //int i;
unsigned int frame_length_samples = frame_parms->samples_per_subframe * 10; unsigned int frame_length_samples = frame_parms->samples_per_subframe * 10;
unsigned int rx_offset; unsigned int rx_offset;
//NR_UE_PDCCH *pdcch_vars = ue->pdcch_vars[ue->current_thread_id[Ns>>1]][0]; NR_UE_PDCCH *pdcch_vars = ue->pdcch_vars[ue->current_thread_id[Ns>>1]][0];
uint16_t coreset_start_subcarrier = frame_parms->first_carrier_offset+516; uint16_t coreset_start_subcarrier = frame_parms->first_carrier_offset+((int)floor(frame_parms->ssb_start_subcarrier/NR_NB_SC_PER_RB)+pdcch_vars->coreset[0].rb_offset)*NR_NB_SC_PER_RB;
uint16_t nb_rb_coreset = 24; uint16_t nb_rb_coreset = 24;
uint16_t bwp_start_subcarrier = frame_parms->first_carrier_offset; uint16_t bwp_start_subcarrier = frame_parms->first_carrier_offset;
uint16_t nb_rb_pdsch = 100; uint16_t nb_rb_pdsch = 100;
...@@ -128,6 +133,12 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, ...@@ -128,6 +133,12 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
// Align with 256 bit // Align with 256 bit
// rx_offset = rx_offset&0xfffffff8; // rx_offset = rx_offset&0xfffffff8;
#ifdef DEBUG_FEP
// if (ue->frame <100)
/*LOG_I(PHY,*/printf("slot_fep: frame %d: slot %d, symbol %d, nb_prefix_samples %d, nb_prefix_samples0 %d, slot_offset %d, subframe_offset %d, sample_offset %d,rx_offset %d, frame_length_samples %d\n", ue->proc.proc_rxtx[(Ns>>1)&1].frame_rx,Ns, symbol,
nb_prefix_samples,nb_prefix_samples0,slot_offset,subframe_offset,sample_offset,rx_offset,frame_length_samples);
#endif
if (l==0) { if (l==0) {
if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size)) if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size))
...@@ -156,11 +167,6 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, ...@@ -156,11 +167,6 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
rx_offset += (frame_parms->ofdm_symbol_size+nb_prefix_samples)*l;// + rx_offset += (frame_parms->ofdm_symbol_size+nb_prefix_samples)*l;// +
// (frame_parms->ofdm_symbol_size+nb_prefix_samples)*(l-1); // (frame_parms->ofdm_symbol_size+nb_prefix_samples)*(l-1);
#ifdef DEBUG_FEP
// if (ue->frame <100)
LOG_I(PHY,"slot_fep: frame %d: slot %d, symbol %d, nb_prefix_samples %d, nb_prefix_samples0 %d, slot_offset %d, subframe_offset %d, sample_offset %d,rx_offset %d, frame_length_samples %d\n", ue->proc.proc_rxtx[(Ns>>1)&1].frame_rx,Ns, symbol,
nb_prefix_samples,nb_prefix_samples0,slot_offset,subframe_offset,sample_offset,rx_offset,frame_length_samples);
#endif
if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size)) if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size))
memcpy((void *)&common_vars->rxdata[aa][frame_length_samples], memcpy((void *)&common_vars->rxdata[aa][frame_length_samples],
......
...@@ -20,17 +20,18 @@ ...@@ -20,17 +20,18 @@
*/ */
/*! \file PHY/NR_REFSIG/nr_dl_dmrs.c /*! \file PHY/NR_REFSIG/nr_dl_dmrs.c
* \brief Top-level routines for generating DMRS from 38-211 * \brief Top-level routines for generating DMRS from 38-211
* \author * \author
* \date 2018 * \date 2018
* \version 0.1 * \version 0.1
* \company Eurecom * \company Eurecom
* \email: * \email:
* \note * \note
* \warning * \warning
*/ */
//#define DEBUG_DL_DMRS //#define DEBUG_DL_DMRS
#define DEBUG_PDCCH
//#define NR_PBCH_DMRS_LENGTH_DWORD 5 //#define NR_PBCH_DMRS_LENGTH_DWORD 5
//#define NR_PBCH_DMRS_LENGTH 144 //#define NR_PBCH_DMRS_LENGTH 144
...@@ -44,6 +45,10 @@ ...@@ -44,6 +45,10 @@
//#include "nr_mod_table.h" //#include "nr_mod_table.h"
#include "common/utils/LOG/log.h" #include "common/utils/LOG/log.h"
#ifdef LOG_I
#undef LOG_I
#define LOG_I(A,B...) printf(B)
#endif
/*Table 7.4.1.1.2-1/2 from 38.211 */ /*Table 7.4.1.1.2-1/2 from 38.211 */
int wf1[8][2] = {{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,1}}; int wf1[8][2] = {{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,1}};
int wt1[8][2] = {{1,1},{1,1},{1,1},{1,1},{1,-1},{1,-1},{1,-1},{1,-1}}; int wt1[8][2] = {{1,1},{1,1},{1,1},{1,1},{1,-1},{1,-1},{1,-1},{1,-1}};
...@@ -61,7 +66,7 @@ short nr_rx_mod_table[NR_MOD_TABLE_SIZE_SHORT] = {0,0,23170,-23170,-23170,23170, ...@@ -61,7 +66,7 @@ short nr_rx_mod_table[NR_MOD_TABLE_SIZE_SHORT] = {0,0,23170,-23170,-23170,23170,
unsigned short p, unsigned short p,
int length_dmrs, int length_dmrs,
unsigned short nb_rb_coreset) unsigned short nb_rb_coreset)
{ {
int32_t qpsk[4],n; int32_t qpsk[4],n;
int w,ind,l,ind_dword,ind_qpsk_symb,kp,k; int w,ind,l,ind_dword,ind_qpsk_symb,kp,k;
short pamp; short pamp;
...@@ -88,11 +93,11 @@ short nr_rx_mod_table[NR_MOD_TABLE_SIZE_SHORT] = {0,0,23170,-23170,-23170,23170, ...@@ -88,11 +93,11 @@ short nr_rx_mod_table[NR_MOD_TABLE_SIZE_SHORT] = {0,0,23170,-23170,-23170,23170,
output[k] = qpsk[(nr_gold_pdcch[eNB_offset][Ns][l][ind_dword]>>(2*ind_qpsk_symb))&3]; output[k] = qpsk[(nr_gold_pdcch[eNB_offset][Ns][l][ind_dword]>>(2*ind_qpsk_symb))&3];
#ifdef DEBUG_DL_DMRS #ifdef DEBUG_DL_DMRS
LOG_I(PHY,"Ns %d, p %d, ind_dword %d, ind_qpsk_symbol %d\n", LOG_I(PHY,"Ns %d, p %d, ind_dword %d, ind_qpsk_symbol %d\n",
Ns,p,idx_dword,idx_qpsk_symb); Ns,p,idx_dword,idx_qpsk_symb);
LOG_I(PHY,"index = %d\n",(nr_gold_pdsch[0][Ns][lprime][ind_dword]>>(2*ind_qpsk_symb))&3); LOG_I(PHY,"index = %d\n",(nr_gold_pdsch[0][Ns][lprime][ind_dword]>>(2*ind_qpsk_symb))&3);
#endif #endif
k++; k++;
} }
...@@ -103,7 +108,7 @@ short nr_rx_mod_table[NR_MOD_TABLE_SIZE_SHORT] = {0,0,23170,-23170,-23170,23170, ...@@ -103,7 +108,7 @@ short nr_rx_mod_table[NR_MOD_TABLE_SIZE_SHORT] = {0,0,23170,-23170,-23170,23170,
} }
return(0); return(0);
}*/ }*/
int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue, int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue,
uint8_t eNB_offset, uint8_t eNB_offset,
...@@ -172,8 +177,8 @@ int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue, ...@@ -172,8 +177,8 @@ int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue,
#ifdef DEBUG_DL_DMRS #ifdef DEBUG_DL_DMRS
LOG_I(PHY,"Ns %d, p %d, ind_dword %d, ind_qpsk_symbol %d\n", LOG_I(PHY,"Ns %d, p %d, ind_dword %d, ind_qpsk_symbol %d\n",
Ns,p,idx_dword,idx_qpsk_symb); Ns,p,ind_dword,ind_qpsk_symb);
LOG_I(PHY,"index = %d\n",(nr_gold_pdsch[0][Ns][lprime][ind_dword]>>(2*ind_qpsk_symb))&3); LOG_I(PHY,"index = %d\n",(nr_gold_pdsch[0][Ns][lp][ind_dword]>>(2*ind_qpsk_symb))&3);
#endif #endif
k++; k++;
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#define DEBUG_CHANNEL_CODING #define DEBUG_CHANNEL_CODING
#define PDCCH_TEST_POLAR_TEMP_FIX #define PDCCH_TEST_POLAR_TEMP_FIX
extern short nr_mod_table[NR_MOD_TABLE_SIZE_SHORT]; extern short nr_mod_table[NR_MOD_TABLE_SIZE_SHORT];
uint16_t nr_get_dci_size(nfapi_nr_dci_format_e format, uint16_t nr_get_dci_size(nfapi_nr_dci_format_e format,
...@@ -185,10 +186,12 @@ uint8_t nr_generate_dci_top(NR_gNB_PDCCH pdcch_vars, ...@@ -185,10 +186,12 @@ uint8_t nr_generate_dci_top(NR_gNB_PDCCH pdcch_vars,
* in frequency: the first subcarrier is obtained by adding the first CRB overlapping the SSB and the rb_offset * in frequency: the first subcarrier is obtained by adding the first CRB overlapping the SSB and the rb_offset
* in time: by its first slot and its first symbol*/ * in time: by its first slot and its first symbol*/
uint16_t cset_start_sc = frame_parms.first_carrier_offset + ((int)floor(frame_parms.ssb_start_subcarrier/NR_NB_SC_PER_RB)+pdcch_params.rb_offset)*NR_NB_SC_PER_RB; uint16_t cset_start_sc = frame_parms.first_carrier_offset + ((int)floor(frame_parms.ssb_start_subcarrier/NR_NB_SC_PER_RB)+pdcch_params.rb_offset)*NR_NB_SC_PER_RB;
uint8_t cset_start_symb = pdcch_params.first_slot*frame_parms.symbols_per_slot + pdcch_params.first_symbol; // uint8_t cset_start_symb = pdcch_params.first_slot*frame_parms.symbols_per_slot + pdcch_params.first_symbol;
uint8_t cset_start_symb = pdcch_params.first_symbol;
uint8_t cset_nsymb = pdcch_params.n_symb; uint8_t cset_nsymb = pdcch_params.n_symb;
dci_idx = 0; dci_idx = 0;
/// DMRS QPSK modulation /// DMRS QPSK modulation
/*There is a need to shift from which index the pregenerated DMRS sequence is used /*There is a need to shift from which index the pregenerated DMRS sequence is used
* see 38211 r15.2.0 section 7.4.1.3.2: assumption is the reference point for k refers to the DMRS sequence*/ * see 38211 r15.2.0 section 7.4.1.3.2: assumption is the reference point for k refers to the DMRS sequence*/
...@@ -278,10 +281,10 @@ printf("scrambled output: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%0 ...@@ -278,10 +281,10 @@ printf("scrambled output: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%0
} }
} }
#ifdef DEBUG_DCI #ifdef DEBUG_DCI
printf("\n Ordered REG list:\n"); printf("\n Ordered REG list:\n");
for (int i=0; i<nb_regs; i++) for (int i=0; i<nb_regs; i++)
printf("%d\t",reg_mapping_list[i].reg_idx ); printf("%d\t",reg_mapping_list[i].reg_idx );
printf("\n"); printf("\n");
#endif #endif
if (pdcch_params.precoder_granularity == NFAPI_NR_CSET_ALL_CONTIGUOUS_RBS) { if (pdcch_params.precoder_granularity == NFAPI_NR_CSET_ALL_CONTIGUOUS_RBS) {
...@@ -292,6 +295,9 @@ printf("\n"); ...@@ -292,6 +295,9 @@ printf("\n");
while (dmrs_idx<3*pdcch_params.n_rb) { while (dmrs_idx<3*pdcch_params.n_rb) {
((int16_t*)txdataF[aa])[(l*frame_parms.ofdm_symbol_size + k)<<1] = (a * mod_dmrs[l][dmrs_idx<<1]) >> 15; ((int16_t*)txdataF[aa])[(l*frame_parms.ofdm_symbol_size + k)<<1] = (a * mod_dmrs[l][dmrs_idx<<1]) >> 15;
((int16_t*)txdataF[aa])[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = (a * mod_dmrs[l][(dmrs_idx<<1) + 1]) >> 15; ((int16_t*)txdataF[aa])[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = (a * mod_dmrs[l][(dmrs_idx<<1) + 1]) >> 15;
#ifdef DEBUG_PDCCH_DMRS
printf("symbol %d position %d => (%d,%d)\n",l,k,((int16_t*)txdataF[aa])[(l*frame_parms.ofdm_symbol_size + k)<<1] , ((int16_t*)txdataF[aa])[((l*frame_parms.ofdm_symbol_size + k)<<1)+1]);
#endif
k+=4; k+=4;
if (k >= frame_parms.ofdm_symbol_size) if (k >= frame_parms.ofdm_symbol_size)
k -= frame_parms.ofdm_symbol_size; k -= frame_parms.ofdm_symbol_size;
...@@ -315,6 +321,9 @@ printf("\n"); ...@@ -315,6 +321,9 @@ printf("\n");
if (pdcch_params.precoder_granularity == NFAPI_NR_CSET_SAME_AS_REG_BUNDLE) { if (pdcch_params.precoder_granularity == NFAPI_NR_CSET_SAME_AS_REG_BUNDLE) {
((int16_t*)txdataF[aa])[(l*frame_parms.ofdm_symbol_size + k)<<1] = (a * mod_dmrs[l][dmrs_idx<<1]) >> 15; ((int16_t*)txdataF[aa])[(l*frame_parms.ofdm_symbol_size + k)<<1] = (a * mod_dmrs[l][dmrs_idx<<1]) >> 15;
((int16_t*)txdataF[aa])[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = (a * mod_dmrs[l][(dmrs_idx<<1) + 1]) >> 15; ((int16_t*)txdataF[aa])[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = (a * mod_dmrs[l][(dmrs_idx<<1) + 1]) >> 15;
#ifdef DEBUG_PDCCH_DMRS
printf("l %d position %d => (%d,%d)\n",l,k,((int16_t*)txdataF[aa])[(l*frame_parms.ofdm_symbol_size + k)<<1] , ((int16_t*)txdataF[aa])[((l*frame_parms.ofdm_symbol_size + k)<<1)+1]);
#endif
k_prime++; k_prime++;
dmrs_idx++; dmrs_idx++;
} }
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
#include "PHY/NR_REFSIG/refsig_defs_ue.h" #include "PHY/NR_REFSIG/refsig_defs_ue.h"
#include "filt16a_32.h" #include "filt16a_32.h"
#include "T.h" #include "T.h"
//#define DEBUG_CH #define DEBUG_CH
int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
...@@ -315,7 +315,7 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, ...@@ -315,7 +315,7 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
printf("rxF addr %p\n", rxF); printf("rxF addr %p\n", rxF);
printf("dl_ch addr %p\n",dl_ch); printf("dl_ch addr %p\n",dl_ch);
//#endif //#endif
if ((ue->frame_parms.N_RB_DL&1)==0) { // if ((ue->frame_parms.N_RB_DL&1)==0) {
// Treat first 2 pilots specially (left edge) // Treat first 2 pilots specially (left edge)
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
...@@ -421,7 +421,7 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, ...@@ -421,7 +421,7 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
} }
} //}
} }
......
...@@ -83,16 +83,16 @@ typedef struct { ...@@ -83,16 +83,16 @@ typedef struct {
} NR_gNB_COMMON; } NR_gNB_COMMON;
/// Context data structure for RX/TX portion of subframe processing /// Context data structure for RX/TX portion of slot processing
typedef struct { typedef struct {
/// Component Carrier index /// Component Carrier index
uint8_t CC_id; uint8_t CC_id;
/// timestamp transmitted to HW /// timestamp transmitted to HW
openair0_timestamp timestamp_tx; openair0_timestamp timestamp_tx;
/// subframe to act upon for transmission /// slot to act upon for transmission
int subframe_tx; int slot_tx;
/// subframe to act upon for reception /// slot to act upon for reception
int subframe_rx; int slot_rx;
/// frame to act upon for transmission /// frame to act upon for transmission
int frame_tx; int frame_tx;
/// frame to act upon for reception /// frame to act upon for reception
...@@ -120,7 +120,7 @@ typedef struct { ...@@ -120,7 +120,7 @@ typedef struct {
} gNB_L1_rxtx_proc_t; } gNB_L1_rxtx_proc_t;
/// Context data structure for eNB subframe processing /// Context data structure for eNB slot processing
typedef struct gNB_L1_proc_t_s { typedef struct gNB_L1_proc_t_s {
/// Component Carrier index /// Component Carrier index
uint8_t CC_id; uint8_t CC_id;
...@@ -130,10 +130,10 @@ typedef struct gNB_L1_proc_t_s { ...@@ -130,10 +130,10 @@ typedef struct gNB_L1_proc_t_s {
openair0_timestamp timestamp_rx; openair0_timestamp timestamp_rx;
/// timestamp to send to "slave rru" /// timestamp to send to "slave rru"
openair0_timestamp timestamp_tx; openair0_timestamp timestamp_tx;
/// subframe to act upon for reception /// slot to act upon for reception
int subframe_rx; int slot_rx;
/// subframe to act upon for PRACH /// slot to act upon for PRACH
int subframe_prach; int slot_prach;
/// frame to act upon for reception /// frame to act upon for reception
int frame_rx; int frame_rx;
/// frame to act upon for transmission /// frame to act upon for transmission
...@@ -391,7 +391,7 @@ typedef struct PHY_VARS_gNB_s { ...@@ -391,7 +391,7 @@ typedef struct PHY_VARS_gNB_s {
/// cba_last successful reception for each group, used for collision detection /// cba_last successful reception for each group, used for collision detection
uint8_t cba_last_reception[4]; uint8_t cba_last_reception[4];
// Pointers for active physicalConfigDedicated to be applied in current subframe // Pointers for active physicalConfigDedicated to be applied in current slot
struct PhysicalConfigDedicated *physicalConfigDedicated[NUMBER_OF_UE_MAX]; struct PhysicalConfigDedicated *physicalConfigDedicated[NUMBER_OF_UE_MAX];
......
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h" #include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
#define nr_subframe_t lte_subframe_t #define nr_subframe_t lte_subframe_t
#define nr_slot_t lte_subframe_t
#define MAX_NUM_SUBCARRIER_SPACING 5 #define MAX_NUM_SUBCARRIER_SPACING 5
...@@ -209,12 +210,16 @@ typedef struct NR_DL_FRAME_PARMS { ...@@ -209,12 +210,16 @@ typedef struct NR_DL_FRAME_PARMS {
uint16_t slots_per_frame; uint16_t slots_per_frame;
/// Number of samples in a subframe /// Number of samples in a subframe
uint32_t samples_per_subframe; uint32_t samples_per_subframe;
/// Number of samples in a slot
uint32_t samples_per_slot;
/// Number of OFDM/SC-FDMA symbols in one subframe (to be modified to account for potential different in UL/DL) /// Number of OFDM/SC-FDMA symbols in one subframe (to be modified to account for potential different in UL/DL)
uint16_t symbols_per_tti; uint16_t symbols_per_tti;
/// Number of samples in a radio frame /// Number of samples in a radio frame
uint32_t samples_per_frame; uint32_t samples_per_frame;
/// Number of samples in a subframe without CP /// Number of samples in a subframe without CP
uint32_t samples_per_subframe_wCP; uint32_t samples_per_subframe_wCP;
/// Number of samples in a slot without CP
uint32_t samples_per_slot_wCP;
/// Number of samples in a radio frame without CP /// Number of samples in a radio frame without CP
uint32_t samples_per_frame_wCP; uint32_t samples_per_frame_wCP;
/// Number of samples in a tti (same as subrame in LTE, depending on numerology in NR) /// Number of samples in a tti (same as subrame in LTE, depending on numerology in NR)
......
...@@ -55,19 +55,19 @@ void handle_nr_nfapi_bch_pdu(PHY_VARS_gNB *gNB, ...@@ -55,19 +55,19 @@ void handle_nr_nfapi_bch_pdu(PHY_VARS_gNB *gNB,
void handle_nfapi_nr_dci_dl_pdu(PHY_VARS_gNB *gNB, void handle_nfapi_nr_dci_dl_pdu(PHY_VARS_gNB *gNB,
int frame, int subframe, int frame, int slot,
gNB_L1_rxtx_proc_t *proc, gNB_L1_rxtx_proc_t *proc,
nfapi_nr_dl_config_request_pdu_t *dl_config_pdu) nfapi_nr_dl_config_request_pdu_t *dl_config_pdu)
{ {
int idx = subframe&1; int idx = slot&1;
NR_gNB_PDCCH *pdcch_vars = &gNB->pdcch_vars; NR_gNB_PDCCH *pdcch_vars = &gNB->pdcch_vars;
LOG_D(PHY,"Frame %d, Subframe %d: DCI processing - populating pdcch_vars->dci_alloc[%d] proc:subframe_tx:%d idx:%d pdcch_vars->num_dci:%d\n",frame,subframe, pdcch_vars->num_dci, proc->subframe_tx, idx, pdcch_vars->num_dci); LOG_D(PHY,"Frame %d, Slot %d: DCI processing - populating pdcch_vars->dci_alloc[%d] proc:slot_tx:%d idx:%d pdcch_vars->num_dci:%d\n",frame,slot, pdcch_vars->num_dci, proc->slot_tx, idx, pdcch_vars->num_dci);
// copy dci configuration into gNB structure // copy dci configuration into gNB structure
nr_fill_dci_and_dlsch(gNB,frame,subframe,proc,&pdcch_vars->dci_alloc[pdcch_vars->num_dci],dl_config_pdu); nr_fill_dci_and_dlsch(gNB,frame,slot,proc,&pdcch_vars->dci_alloc[pdcch_vars->num_dci],dl_config_pdu);
LOG_D(PHY,"Frame %d, Subframe %d: DCI processing - populated pdcch_vars->dci_alloc[%d] proc:subframe_tx:%d idx:%d pdcch_vars->num_dci:%d\n",proc->frame_tx,proc->subframe_tx, pdcch_vars->num_dci, proc->subframe_tx, idx, pdcch_vars->num_dci); LOG_D(PHY,"Frame %d, Slot %d: DCI processing - populated pdcch_vars->dci_alloc[%d] proc:slot_tx:%d idx:%d pdcch_vars->num_dci:%d\n",proc->frame_tx,proc->slot_tx, pdcch_vars->num_dci, proc->slot_tx, idx, pdcch_vars->num_dci);
} }
...@@ -80,7 +80,7 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){ ...@@ -80,7 +80,7 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){
nfapi_nr_dl_config_request_t *DL_req = Sched_INFO->DL_req; nfapi_nr_dl_config_request_t *DL_req = Sched_INFO->DL_req;
nfapi_tx_request_t *TX_req = Sched_INFO->TX_req; nfapi_tx_request_t *TX_req = Sched_INFO->TX_req;
frame_t frame = Sched_INFO->frame; frame_t frame = Sched_INFO->frame;
sub_frame_t subframe = Sched_INFO->subframe; sub_frame_t slot = Sched_INFO->slot;
AssertFatal(RC.gNB!=NULL,"RC.gNB is null\n"); AssertFatal(RC.gNB!=NULL,"RC.gNB is null\n");
AssertFatal(RC.gNB[Mod_id]!=NULL,"RC.gNB[%d] is null\n",Mod_id); AssertFatal(RC.gNB[Mod_id]!=NULL,"RC.gNB[%d] is null\n",Mod_id);
...@@ -96,7 +96,7 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){ ...@@ -96,7 +96,7 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){
int i; int i;
LOG_D(PHY,"NFAPI: Sched_INFO:SFN/SF:%04d%d DL_req:SFN/SF:%04d%d:dl_pdu:%d tx_req:SFN/SF:%04d%d:pdus:%d \n", LOG_D(PHY,"NFAPI: Sched_INFO:SFN/SF:%04d%d DL_req:SFN/SF:%04d%d:dl_pdu:%d tx_req:SFN/SF:%04d%d:pdus:%d \n",
frame,subframe, frame,slot,
NFAPI_SFNSF2SFN(DL_req->sfn_sf),NFAPI_SFNSF2SF(DL_req->sfn_sf),number_dl_pdu, NFAPI_SFNSF2SFN(DL_req->sfn_sf),NFAPI_SFNSF2SF(DL_req->sfn_sf),number_dl_pdu,
NFAPI_SFNSF2SFN(TX_req->sfn_sf),NFAPI_SFNSF2SF(TX_req->sfn_sf),TX_req->tx_request_body.number_of_pdus); NFAPI_SFNSF2SFN(TX_req->sfn_sf),NFAPI_SFNSF2SF(TX_req->sfn_sf),TX_req->tx_request_body.number_of_pdus);
...@@ -124,7 +124,7 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){ ...@@ -124,7 +124,7 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){
case NFAPI_NR_DL_CONFIG_DCI_DL_PDU_TYPE: case NFAPI_NR_DL_CONFIG_DCI_DL_PDU_TYPE:
handle_nfapi_nr_dci_dl_pdu(gNB, handle_nfapi_nr_dci_dl_pdu(gNB,
frame, subframe, frame, slot,
proc, proc,
dl_config_pdu); dl_config_pdu);
gNB->pdcch_vars.num_dci++; gNB->pdcch_vars.num_dci++;
......
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
nr_subframe_t nr_subframe_select(nfapi_nr_config_request_t *cfg,unsigned char subframe) nr_subframe_t nr_slot_select(nfapi_nr_config_request_t *cfg,unsigned char slot)
{ {
if (cfg->subframe_config.duplex_mode.value == FDD) if (cfg->subframe_config.duplex_mode.value == FDD)
return(SF_DL); return(SF_DL);
......
...@@ -116,32 +116,32 @@ void nr_set_ssb_first_subcarrier(nfapi_nr_config_request_t *cfg, NR_DL_FRAME_PAR ...@@ -116,32 +116,32 @@ void nr_set_ssb_first_subcarrier(nfapi_nr_config_request_t *cfg, NR_DL_FRAME_PAR
LOG_D(PHY, "SSB first subcarrier %d (%d,%d)\n", fp->ssb_start_subcarrier,start_rb,cfg->sch_config.ssb_subcarrier_offset.value); LOG_D(PHY, "SSB first subcarrier %d (%d,%d)\n", fp->ssb_start_subcarrier,start_rb,cfg->sch_config.ssb_subcarrier_offset.value);
} }
void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int subframe) { void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int slot) {
NR_DL_FRAME_PARMS *fp=&gNB->frame_parms; NR_DL_FRAME_PARMS *fp=&gNB->frame_parms;
nfapi_nr_config_request_t *cfg = &gNB->gNB_config; nfapi_nr_config_request_t *cfg = &gNB->gNB_config;
int **txdataF = gNB->common_vars.txdataF; int **txdataF = gNB->common_vars.txdataF;
uint8_t *pbch_pdu=&gNB->pbch_pdu[0]; uint8_t *pbch_pdu=&gNB->pbch_pdu[0];
int ss_subframe = (cfg->sch_config.half_frame_index.value)? 5 : 0; int ss_slot = (cfg->sch_config.half_frame_index.value)? 10 : 0;
uint8_t Lmax, ssb_index=0, n_hf=0; uint8_t Lmax, ssb_index=0, n_hf=0;
LOG_D(PHY,"common_signal_procedures: frame %d, subframe %d\n",frame,subframe); LOG_D(PHY,"common_signal_procedures: frame %d, slot %d\n",frame,slot);
int ssb_start_symbol = nr_get_ssb_start_symbol(cfg, fp); int ssb_start_symbol = nr_get_ssb_start_symbol(cfg, fp);
nr_set_ssb_first_subcarrier(cfg, fp); nr_set_ssb_first_subcarrier(cfg, fp);
Lmax = (fp->dl_CarrierFreq < 3e9)? 4:8; Lmax = (fp->dl_CarrierFreq < 3e9)? 4:8;
if (subframe == ss_subframe) if (slot == ss_slot)
{ {
// Current implementation is based on SSB in first half frame, first candidate // Current implementation is based on SSB in first half frame, first candidate
LOG_D(PHY,"SS TX: frame %d, subframe %d, start_symbol %d\n",frame,subframe, ssb_start_symbol); LOG_D(PHY,"SS TX: frame %d, slot %d, start_symbol %d\n",frame,slot, ssb_start_symbol);
nr_generate_pss(gNB->d_pss, txdataF, AMP, ssb_start_symbol, cfg, fp); nr_generate_pss(gNB->d_pss, txdataF, AMP, ssb_start_symbol, cfg, fp);
nr_generate_sss(gNB->d_sss, txdataF, AMP_OVER_2, ssb_start_symbol, cfg, fp); nr_generate_sss(gNB->d_sss, txdataF, AMP_OVER_2, ssb_start_symbol, cfg, fp);
if (!(frame&7)){ if (!(frame&7)){
LOG_D(PHY,"%d.%d : pbch_configured %d\n",frame,subframe,gNB->pbch_configured); LOG_D(PHY,"%d.%d : pbch_configured %d\n",frame,slot,gNB->pbch_configured);
if (gNB->pbch_configured != 1)return; if (gNB->pbch_configured != 1)return;
gNB->pbch_configured = 0; gNB->pbch_configured = 0;
} }
...@@ -165,7 +165,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, ...@@ -165,7 +165,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
{ {
int aa; int aa;
int frame=proc->frame_tx; int frame=proc->frame_tx;
int subframe=proc->subframe_tx; int slot=proc->slot_tx;
uint8_t num_dci=0; uint8_t num_dci=0;
NR_DL_FRAME_PARMS *fp=&gNB->frame_parms; NR_DL_FRAME_PARMS *fp=&gNB->frame_parms;
...@@ -173,33 +173,32 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, ...@@ -173,33 +173,32 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
int offset = gNB->CC_id; int offset = gNB->CC_id;
if ((cfg->subframe_config.duplex_mode.value == TDD) && (nr_subframe_select(cfg,subframe)==SF_UL)) return; if ((cfg->subframe_config.duplex_mode.value == TDD) && (nr_slot_select(cfg,slot)==SF_UL)) return;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_TX+offset,1); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_TX+offset,1);
if (do_meas==1) start_meas(&gNB->phy_proc_tx); if (do_meas==1) start_meas(&gNB->phy_proc_tx);
// clear the transmit data array for the current subframe // clear the transmit data array for the current subframe
for (aa=0; aa<cfg->rf_config.tx_antenna_ports.value; aa++) { for (aa=0; aa<cfg->rf_config.tx_antenna_ports.value; aa++) {
memset(gNB->common_vars.txdataF[aa],0,fp->samples_per_subframe_wCP*sizeof(int32_t)); memset(gNB->common_vars.txdataF[aa],0,fp->samples_per_slot_wCP*sizeof(int32_t));
} }
if (nfapi_mode == 0 || nfapi_mode == 1) { if (nfapi_mode == 0 || nfapi_mode == 1) {
nr_common_signal_procedures(gNB,frame, subframe); nr_common_signal_procedures(gNB,frame, slot);
//if (frame == 9) //if (frame == 9)
//write_output("txdataF.m","txdataF",gNB->common_vars.txdataF[aa],fp->samples_per_frame_wCP, 1, 1); //write_output("txdataF.m","txdataF",gNB->common_vars.txdataF[aa],fp->samples_per_frame_wCP, 1, 1);
} }
num_dci = gNB->pdcch_vars.num_dci; num_dci = gNB->pdcch_vars.num_dci;
if (num_dci) { if (num_dci) {
LOG_I(PHY, "[gNB %d] Frame %d subframe %d \ LOG_I(PHY, "[gNB %d] Frame %d slot %d \
Calling nr_generate_dci_top (number of DCI %d)\n", gNB->Mod_id, frame, subframe, num_dci); Calling nr_generate_dci_top (number of DCI %d)\n", gNB->Mod_id, frame, slot, num_dci);
uint8_t slot_idx = gNB->pdcch_vars.dci_alloc[0].pdcch_params.first_slot;
if (nfapi_mode == 0 || nfapi_mode == 1) if (nfapi_mode == 0 || nfapi_mode == 1)
nr_generate_dci_top(gNB->pdcch_vars, nr_generate_dci_top(gNB->pdcch_vars,
&gNB->nrPolar_params, &gNB->nrPolar_params,
gNB->nr_gold_pdcch_dmrs[slot_idx], gNB->nr_gold_pdcch_dmrs[slot],
gNB->common_vars.txdataF, gNB->common_vars.txdataF,
AMP, *fp, *cfg); AMP, *fp, *cfg);
} }
......
...@@ -34,16 +34,16 @@ ...@@ -34,16 +34,16 @@
#include "PHY/NR_TRANSPORT/nr_dci.h" #include "PHY/NR_TRANSPORT/nr_dci.h"
lte_subframe_t nr_subframe_select (nfapi_nr_config_request_t *cfg, unsigned char subframe); nr_slot_t nr_slot_select (nfapi_nr_config_request_t *cfg, unsigned char slot);
void nr_set_ssb_first_subcarrier(nfapi_nr_config_request_t *cfg, NR_DL_FRAME_PARMS *fp); void nr_set_ssb_first_subcarrier(nfapi_nr_config_request_t *cfg, NR_DL_FRAME_PARMS *fp);
void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, gNB_L1_rxtx_proc_t *proc, int do_meas); void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, gNB_L1_rxtx_proc_t *proc, int do_meas);
void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int subframe); void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int slot);
void nr_init_feptx_thread(RU_t *ru,pthread_attr_t *attr_feptx); void nr_init_feptx_thread(RU_t *ru,pthread_attr_t *attr_feptx);
void nr_feptx_ofdm(RU_t *ru); void nr_feptx_ofdm(RU_t *ru);
void nr_feptx_ofdm_2thread(RU_t *ru); void nr_feptx_ofdm_2thread(RU_t *ru);
void nr_feptx0(RU_t *ru,int slot); void nr_feptx0(RU_t *ru,int slot);
void nr_configure_css_dci_from_mib(nfapi_nr_dl_config_pdcch_parameters_rel15_t* pdcch_params, void nr_configure_css_dci_initial(nfapi_nr_dl_config_pdcch_parameters_rel15_t* pdcch_params,
nr_scs_e scs_common, nr_scs_e scs_common,
nr_scs_e pdcch_scs, nr_scs_e pdcch_scs,
nr_frequency_range_e freq_range, nr_frequency_range_e freq_range,
......
...@@ -49,14 +49,15 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){ ...@@ -49,14 +49,15 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
uint32_t i; uint32_t i;
if(scheduled_response != NULL){ if(scheduled_response != NULL){
// Note: we have to handle the thread IDs for this. To be revisited completely.
NR_UE_PDCCH *pdcch_vars2 = PHY_vars_UE_g[module_id][cc_id]->pdcch_vars[0][0]; NR_UE_PDCCH *pdcch_vars2 = PHY_vars_UE_g[module_id][cc_id]->pdcch_vars[0][0];
NR_UE_DLSCH_t *dlsch0 = PHY_vars_UE_g[module_id][cc_id]->dlsch[0][0]; NR_UE_DLSCH_t *dlsch0 = PHY_vars_UE_g[module_id][cc_id]->dlsch[0][0];
NR_UE_ULSCH_t *ulsch0 = PHY_vars_UE_g[module_id][cc_id]->ulsch[0]; NR_UE_ULSCH_t *ulsch0 = PHY_vars_UE_g[module_id][cc_id]->ulsch[0];
NR_DL_FRAME_PARMS frame_parms = PHY_vars_UE_g[module_id][cc_id]->frame_parms; NR_DL_FRAME_PARMS frame_parms = PHY_vars_UE_g[module_id][cc_id]->frame_parms;
PRACH_RESOURCES_t *prach_resources = PHY_vars_UE_g[module_id][cc_id]->prach_resources[0]; PRACH_RESOURCES_t *prach_resources = PHY_vars_UE_g[module_id][cc_id]->prach_resources[0];
// PUCCH_ConfigCommon_nr_t *pucch_config_common = PHY_vars_UE_g[module_id][cc_id]->pucch_config_common_nr[0]; // PUCCH_ConfigCommon_nr_t *pucch_config_common = PHY_vars_UE_g[module_id][cc_id]->pucch_config_common_nr[0];
// PUCCH_Config_t *pucch_config_dedicated = PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0]; // PUCCH_Config_t *pucch_config_dedicated = PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0];
if(scheduled_response->dl_config != NULL){ if(scheduled_response->dl_config != NULL){
fapi_nr_dl_config_request_t *dl_config = scheduled_response->dl_config; fapi_nr_dl_config_request_t *dl_config = scheduled_response->dl_config;
...@@ -122,11 +123,11 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){ ...@@ -122,11 +123,11 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
printf(">>>> \tdlsch0->g_pucch=%d\tdlsch0_harq.mcs=%d\n",dlsch0->g_pucch,dlsch0_harq.mcs); printf(">>>> \tdlsch0->g_pucch=%d\tdlsch0_harq.mcs=%d\n",dlsch0->g_pucch,dlsch0_harq.mcs);
//for (int j = 0 ; j<1000; j++) printf("\nk = %d",j); //for (int j = 0 ; j<1000; j++) printf("\nk = %d",j);
#if 0 #if 0
dlsch0->harq_processes[current_harq_pid]->mcs = dlsch_config_pdu->mcs; dlsch0->harq_processes[current_harq_pid]->mcs = dlsch_config_pdu->mcs;
dlsch0->g_pucch = dlsch_config_pdu->accumulated_delta_PUCCH; dlsch0->g_pucch = dlsch_config_pdu->accumulated_delta_PUCCH;
//pdlsch0->rnti = rnti; //pdlsch0->rnti = rnti;
#endif #endif
} }
} }
}else{ }else{
...@@ -169,7 +170,7 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){ ...@@ -169,7 +170,7 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
PHY_vars_UE_g[module_id][cc_id]->pucch_config_common_nr[0].pucch_GroupHopping = pucch_config_pdu->pucch_GroupHopping; PHY_vars_UE_g[module_id][cc_id]->pucch_config_common_nr[0].pucch_GroupHopping = pucch_config_pdu->pucch_GroupHopping;
PHY_vars_UE_g[module_id][cc_id]->pucch_config_common_nr[0].hoppingId = pucch_config_pdu->hoppingId; PHY_vars_UE_g[module_id][cc_id]->pucch_config_common_nr[0].hoppingId = pucch_config_pdu->hoppingId;
PHY_vars_UE_g[module_id][cc_id]->pucch_config_common_nr[0].p0_nominal = pucch_config_pdu->p0_nominal; PHY_vars_UE_g[module_id][cc_id]->pucch_config_common_nr[0].p0_nominal = pucch_config_pdu->p0_nominal;
/* pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.initialCyclicShift = pucch_config_pdu->initialCyclicShift; /* pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.initialCyclicShift = pucch_config_pdu->initialCyclicShift;
pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.nrofSymbols = pucch_config_pdu->nrofSymbols; pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.nrofSymbols = pucch_config_pdu->nrofSymbols;
pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.startingSymbolIndex = pucch_config_pdu->startingSymbolIndex; pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.startingSymbolIndex = pucch_config_pdu->startingSymbolIndex;
pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.nrofPRBs = pucch_config_pdu->nrofPRBs; pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.nrofPRBs = pucch_config_pdu->nrofPRBs;
......
...@@ -150,7 +150,7 @@ int main(int argc, char **argv) ...@@ -150,7 +150,7 @@ int main(int argc, char **argv)
unsigned char frame_type = 0; unsigned char frame_type = 0;
unsigned char pbch_phase = 0; unsigned char pbch_phase = 0;
int frame=0,subframe=1; int frame=0,slot=1;
int frame_length_complex_samples; int frame_length_complex_samples;
int frame_length_complex_samples_no_prefix; int frame_length_complex_samples_no_prefix;
NR_DL_FRAME_PARMS *frame_parms; NR_DL_FRAME_PARMS *frame_parms;
...@@ -484,6 +484,7 @@ int main(int argc, char **argv) ...@@ -484,6 +484,7 @@ int main(int argc, char **argv)
} }
nr_gold_pbch(UE); nr_gold_pbch(UE);
nr_gold_pdcch(UE,0,2);
RC.nb_nr_macrlc_inst = 1; RC.nb_nr_macrlc_inst = 1;
mac_top_init_gNB(); mac_top_init_gNB();
...@@ -509,11 +510,11 @@ int main(int argc, char **argv) ...@@ -509,11 +510,11 @@ int main(int argc, char **argv)
gNB->pbch_configured = 1; gNB->pbch_configured = 1;
for (int i=0;i<4;i++) gNB->pbch_pdu[i]=i+1; for (int i=0;i<4;i++) gNB->pbch_pdu[i]=i+1;
nr_schedule_css_dlsch_phytest(0,frame,subframe); nr_schedule_css_dlsch_phytest(0,frame,slot);
Sched_INFO.module_id = 0; Sched_INFO.module_id = 0;
Sched_INFO.CC_id = 0; Sched_INFO.CC_id = 0;
Sched_INFO.frame = frame; Sched_INFO.frame = frame;
Sched_INFO.subframe = subframe; Sched_INFO.slot = slot;
Sched_INFO.DL_req = &gNB_mac->DL_req[0]; Sched_INFO.DL_req = &gNB_mac->DL_req[0];
Sched_INFO.UL_req = NULL; Sched_INFO.UL_req = NULL;
Sched_INFO.HI_DCI0_req = NULL; Sched_INFO.HI_DCI0_req = NULL;
...@@ -521,7 +522,7 @@ int main(int argc, char **argv) ...@@ -521,7 +522,7 @@ int main(int argc, char **argv)
nr_schedule_response(&Sched_INFO); nr_schedule_response(&Sched_INFO);
gNB_proc.frame_tx = frame; gNB_proc.frame_tx = frame;
gNB_proc.subframe_tx = subframe; gNB_proc.slot_tx = slot;
phy_procedures_gNB_TX(gNB,&gNB_proc,0); phy_procedures_gNB_TX(gNB,&gNB_proc,0);
//nr_common_signal_procedures (gNB,frame,subframe); //nr_common_signal_procedures (gNB,frame,subframe);
...@@ -660,12 +661,14 @@ int main(int argc, char **argv) ...@@ -660,12 +661,14 @@ int main(int argc, char **argv)
UE->rx_offset=0; UE->rx_offset=0;
UE_proc.frame_rx = frame; UE_proc.frame_rx = frame;
UE_proc.nr_tti_rx= subframe; UE_proc.nr_tti_rx= slot;
UE_proc.subframe_rx = subframe; UE_proc.subframe_rx = slot;
UE_mac->scheduled_response.dl_config = &dl_config; UE_mac->scheduled_response.dl_config = &dl_config;
nr_ue_scheduled_response(&UE_mac->scheduled_response); nr_ue_scheduled_response(&UE_mac->scheduled_response);
printf("Running phy procedures UE RX %d.%d\n",frame,slot);
phy_procedures_nrUE_RX(UE, phy_procedures_nrUE_RX(UE,
&UE_proc, &UE_proc,
0, 0,
......
...@@ -72,6 +72,7 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP, ...@@ -72,6 +72,7 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP,
scs, scs, nr_FR1, 0, 0, scs, scs, nr_FR1, 0, 0,
slots_per_frame, slots_per_frame,
dl_carrier_bandwidth); dl_carrier_bandwidth);
params_rel15->first_slot = 0;
pdu_rel15->frequency_domain_assignment = 5; pdu_rel15->frequency_domain_assignment = 5;
pdu_rel15->time_domain_assignment = 2; pdu_rel15->time_domain_assignment = 2;
......
...@@ -59,7 +59,7 @@ void handle_nr_rach(NR_UL_IND_t *UL_info) { ...@@ -59,7 +59,7 @@ void handle_nr_rach(NR_UL_IND_t *UL_info) {
AssertFatal(UL_info->rach_ind.rach_indication_body.number_of_preambles==1,"More than 1 preamble not supported\n"); AssertFatal(UL_info->rach_ind.rach_indication_body.number_of_preambles==1,"More than 1 preamble not supported\n");
UL_info->rach_ind.rach_indication_body.number_of_preambles=0; UL_info->rach_ind.rach_indication_body.number_of_preambles=0;
LOG_D(MAC,"UL_info[Frame %d, Subframe %d] Calling initiate_ra_proc RACH:SFN/SF:%d\n",UL_info->frame,UL_info->subframe, NFAPI_SFNSF2DEC(UL_info->rach_ind.sfn_sf)); LOG_D(MAC,"UL_info[Frame %d, Slot %d] Calling initiate_ra_proc RACH:SFN/SF:%d\n",UL_info->frame,UL_info->slot, NFAPI_SFNSF2DEC(UL_info->rach_ind.sfn_sf));
initiate_ra_proc(UL_info->module_id, initiate_ra_proc(UL_info->module_id,
UL_info->CC_id, UL_info->CC_id,
NFAPI_SFNSF2SFN(UL_info->rach_ind.sfn_sf), NFAPI_SFNSF2SFN(UL_info->rach_ind.sfn_sf),
...@@ -80,12 +80,12 @@ void handle_nr_rach(NR_UL_IND_t *UL_info) { ...@@ -80,12 +80,12 @@ void handle_nr_rach(NR_UL_IND_t *UL_info) {
for (i=0;i<UL_info->rach_ind_br.rach_indication_body.number_of_preambles;i++) { for (i=0;i<UL_info->rach_ind_br.rach_indication_body.number_of_preambles;i++) {
AssertFatal(UL_info->rach_ind_br.rach_indication_body.preamble_list[i].preamble_rel13.rach_resource_type>0, AssertFatal(UL_info->rach_ind_br.rach_indication_body.preamble_list[i].preamble_rel13.rach_resource_type>0,
"Got regular PRACH preamble, not BL/CE\n"); "Got regular PRACH preamble, not BL/CE\n");
LOG_D(MAC,"Frame %d, Subframe %d Calling initiate_ra_proc (CE_level %d)\n",UL_info->frame,UL_info->subframe, LOG_D(MAC,"Frame %d, Slot %d Calling initiate_ra_proc (CE_level %d)\n",UL_info->frame,UL_info->slot,
UL_info->rach_ind_br.rach_indication_body.preamble_list[i].preamble_rel13.rach_resource_type-1); UL_info->rach_ind_br.rach_indication_body.preamble_list[i].preamble_rel13.rach_resource_type-1);
initiate_ra_proc(UL_info->module_id, initiate_ra_proc(UL_info->module_id,
UL_info->CC_id, UL_info->CC_id,
UL_info->frame, UL_info->frame,
UL_info->subframe, UL_info->slot,
UL_info->rach_ind_br.rach_indication_body.preamble_list[i].preamble_rel8.preamble, UL_info->rach_ind_br.rach_indication_body.preamble_list[i].preamble_rel8.preamble,
UL_info->rach_ind_br.rach_indication_body.preamble_list[i].preamble_rel8.timing_advance, UL_info->rach_ind_br.rach_indication_body.preamble_list[i].preamble_rel8.timing_advance,
UL_info->rach_ind_br.rach_indication_body.preamble_list[i].preamble_rel8.rnti, UL_info->rach_ind_br.rach_indication_body.preamble_list[i].preamble_rel8.rnti,
...@@ -113,7 +113,7 @@ void handle_nr_sr(NR_UL_IND_t *UL_info) { ...@@ -113,7 +113,7 @@ void handle_nr_sr(NR_UL_IND_t *UL_info) {
SR_indication(UL_info->module_id, SR_indication(UL_info->module_id,
UL_info->CC_id, UL_info->CC_id,
UL_info->frame, UL_info->frame,
UL_info->subframe, UL_info->slot,
UL_info->sr_ind.sr_indication_body.sr_pdu_list[i].rx_ue_information.rnti, UL_info->sr_ind.sr_indication_body.sr_pdu_list[i].rx_ue_information.rnti,
UL_info->sr_ind.sr_indication_body.sr_pdu_list[i].ul_cqi_information.ul_cqi); UL_info->sr_ind.sr_indication_body.sr_pdu_list[i].ul_cqi_information.ul_cqi);
} }
...@@ -133,7 +133,7 @@ void handle_nr_cqi(NR_UL_IND_t *UL_info) { ...@@ -133,7 +133,7 @@ void handle_nr_cqi(NR_UL_IND_t *UL_info) {
nfapi_cqi_indication_t ind; nfapi_cqi_indication_t ind;
ind.header.message_id = NFAPI_RX_CQI_INDICATION; ind.header.message_id = NFAPI_RX_CQI_INDICATION;
ind.sfn_sf = UL_info->frame<<4 | UL_info->subframe; ind.sfn_sf = UL_info->frame<<4 | UL_info->slot;
ind.cqi_indication_body = UL_info->cqi_ind; ind.cqi_indication_body = UL_info->cqi_ind;
oai_nfapi_cqi_indication(&ind); oai_nfapi_cqi_indication(&ind);
...@@ -147,7 +147,7 @@ void handle_nr_cqi(NR_UL_IND_t *UL_info) { ...@@ -147,7 +147,7 @@ void handle_nr_cqi(NR_UL_IND_t *UL_info) {
cqi_indication(UL_info->module_id, cqi_indication(UL_info->module_id,
UL_info->CC_id, UL_info->CC_id,
UL_info->frame, UL_info->frame,
UL_info->subframe, UL_info->slot,
UL_info->cqi_ind.cqi_pdu_list[i].rx_ue_information.rnti, UL_info->cqi_ind.cqi_pdu_list[i].rx_ue_information.rnti,
&UL_info->cqi_ind.cqi_pdu_list[i].cqi_indication_rel9, &UL_info->cqi_ind.cqi_pdu_list[i].cqi_indication_rel9,
UL_info->cqi_ind.cqi_raw_pdu_list[i].pdu, UL_info->cqi_ind.cqi_raw_pdu_list[i].pdu,
...@@ -220,11 +220,11 @@ void handle_nr_ulsch(NR_UL_IND_t *UL_info) { ...@@ -220,11 +220,11 @@ void handle_nr_ulsch(NR_UL_IND_t *UL_info) {
UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_ue_information.rnti) { UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_ue_information.rnti) {
LOG_D(PHY, "UL_info->crc_ind.crc_indication_body.crc_pdu_list[%d].crc_indication_rel8.crc_flag:%d\n", j, UL_info->crc_ind.crc_indication_body.crc_pdu_list[j].crc_indication_rel8.crc_flag); LOG_D(PHY, "UL_info->crc_ind.crc_indication_body.crc_pdu_list[%d].crc_indication_rel8.crc_flag:%d\n", j, UL_info->crc_ind.crc_indication_body.crc_pdu_list[j].crc_indication_rel8.crc_flag);
if (UL_info->crc_ind.crc_indication_body.crc_pdu_list[j].crc_indication_rel8.crc_flag == 1) { // CRC error indication if (UL_info->crc_ind.crc_indication_body.crc_pdu_list[j].crc_indication_rel8.crc_flag == 1) { // CRC error indication
LOG_D(MAC,"Frame %d, Subframe %d Calling rx_sdu (CRC error) \n",UL_info->frame,UL_info->subframe); LOG_D(MAC,"Frame %d, Slot %d Calling rx_sdu (CRC error) \n",UL_info->frame,UL_info->slot);
rx_sdu(UL_info->module_id, rx_sdu(UL_info->module_id,
UL_info->CC_id, UL_info->CC_id,
NFAPI_SFNSF2SFN(UL_info->rx_ind.sfn_sf), //UL_info->frame, NFAPI_SFNSF2SFN(UL_info->rx_ind.sfn_sf), //UL_info->frame,
NFAPI_SFNSF2SF(UL_info->rx_ind.sfn_sf), //UL_info->subframe, NFAPI_SFNSF2SF(UL_info->rx_ind.sfn_sf), //UL_info->slot,
UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_ue_information.rnti, UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_ue_information.rnti,
(uint8_t *)NULL, (uint8_t *)NULL,
UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.length, UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.length,
...@@ -232,11 +232,11 @@ void handle_nr_ulsch(NR_UL_IND_t *UL_info) { ...@@ -232,11 +232,11 @@ void handle_nr_ulsch(NR_UL_IND_t *UL_info) {
UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.ul_cqi); UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.ul_cqi);
} }
else { else {
LOG_D(MAC,"Frame %d, Subframe %d Calling rx_sdu (CRC ok) \n",UL_info->frame,UL_info->subframe); LOG_D(MAC,"Frame %d, Slot %d Calling rx_sdu (CRC ok) \n",UL_info->frame,UL_info->slot);
rx_sdu(UL_info->module_id, rx_sdu(UL_info->module_id,
UL_info->CC_id, UL_info->CC_id,
NFAPI_SFNSF2SFN(UL_info->rx_ind.sfn_sf), //UL_info->frame, NFAPI_SFNSF2SFN(UL_info->rx_ind.sfn_sf), //UL_info->frame,
NFAPI_SFNSF2SF(UL_info->rx_ind.sfn_sf), //UL_info->subframe, NFAPI_SFNSF2SF(UL_info->rx_ind.sfn_sf), //UL_info->slot,
UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_ue_information.rnti, UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_ue_information.rnti,
UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].data, UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].data,
UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.length, UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.length,
...@@ -250,12 +250,12 @@ void handle_nr_ulsch(NR_UL_IND_t *UL_info) { ...@@ -250,12 +250,12 @@ void handle_nr_ulsch(NR_UL_IND_t *UL_info) {
} // for (i=0;i<UL_info->rx_ind.number_of_pdus;i++) } // for (i=0;i<UL_info->rx_ind.number_of_pdus;i++)
UL_info->crc_ind.crc_indication_body.number_of_crcs=0; UL_info->crc_ind.crc_indication_body.number_of_crcs=0;
UL_info->rx_ind.rx_indication_body.number_of_pdus = 0; UL_info->rx_ind.rx_indication_body.number_of_pdus = 0;
} // UL_info->rx_ind.rx_indication_body.number_of_pdus>0 && UL_info->subframe && UL_info->crc_ind.crc_indication_body.number_of_crcs>0 } // UL_info->rx_ind.rx_indication_body.number_of_pdus>0 && UL_info->slot && UL_info->crc_ind.crc_indication_body.number_of_crcs>0
else if (UL_info->rx_ind.rx_indication_body.number_of_pdus!=0 || UL_info->crc_ind.crc_indication_body.number_of_crcs!=0) { else if (UL_info->rx_ind.rx_indication_body.number_of_pdus!=0 || UL_info->crc_ind.crc_indication_body.number_of_crcs!=0) {
LOG_E(PHY,"hoping not to have mis-match between CRC ind and RX ind - hopefully the missing message is coming shortly rx_ind:%d(SFN/SF:%05d) crc_ind:%d(SFN/SF:%05d) UL_info(SFN/SF):%04d%d\n", LOG_E(PHY,"hoping not to have mis-match between CRC ind and RX ind - hopefully the missing message is coming shortly rx_ind:%d(SFN/SF:%05d) crc_ind:%d(SFN/SF:%05d) UL_info(SFN/SF):%04d%d\n",
UL_info->rx_ind.rx_indication_body.number_of_pdus, NFAPI_SFNSF2DEC(UL_info->rx_ind.sfn_sf), UL_info->rx_ind.rx_indication_body.number_of_pdus, NFAPI_SFNSF2DEC(UL_info->rx_ind.sfn_sf),
UL_info->crc_ind.crc_indication_body.number_of_crcs, NFAPI_SFNSF2DEC(UL_info->crc_ind.sfn_sf), UL_info->crc_ind.crc_indication_body.number_of_crcs, NFAPI_SFNSF2DEC(UL_info->crc_ind.sfn_sf),
UL_info->frame, UL_info->subframe); UL_info->frame, UL_info->slot);
} }
} }
} }
...@@ -276,7 +276,7 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) ...@@ -276,7 +276,7 @@ void NR_UL_indication(NR_UL_IND_t *UL_info)
gNB_MAC_INST *mac = RC.nrmac[module_id]; gNB_MAC_INST *mac = RC.nrmac[module_id];
LOG_D(PHY,"SFN/SF:%d%d module_id:%d CC_id:%d UL_info[rx_ind:%d harqs:%d crcs:%d cqis:%d preambles:%d sr_ind:%d]\n", LOG_D(PHY,"SFN/SF:%d%d module_id:%d CC_id:%d UL_info[rx_ind:%d harqs:%d crcs:%d cqis:%d preambles:%d sr_ind:%d]\n",
UL_info->frame,UL_info->subframe, UL_info->frame,UL_info->slot,
module_id,CC_id, module_id,CC_id,
UL_info->rx_ind.rx_indication_body.number_of_pdus, UL_info->harq_ind.harq_indication_body.number_of_harqs, UL_info->crc_ind.crc_indication_body.number_of_crcs, UL_info->cqi_ind.number_of_cqis, UL_info->rach_ind.rach_indication_body.number_of_preambles, UL_info->sr_ind.sr_indication_body.number_of_srs); UL_info->rx_ind.rx_indication_body.number_of_pdus, UL_info->harq_ind.harq_indication_body.number_of_harqs, UL_info->crc_ind.crc_indication_body.number_of_crcs, UL_info->cqi_ind.number_of_cqis, UL_info->rach_ind.rach_indication_body.number_of_preambles, UL_info->sr_ind.sr_indication_body.number_of_srs);
...@@ -284,18 +284,18 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) ...@@ -284,18 +284,18 @@ void NR_UL_indication(NR_UL_IND_t *UL_info)
{ {
if (ifi->CC_mask==0) { if (ifi->CC_mask==0) {
ifi->current_frame = UL_info->frame; ifi->current_frame = UL_info->frame;
ifi->current_subframe = UL_info->subframe; ifi->current_slot = UL_info->slot;
} }
else { else {
AssertFatal(UL_info->frame != ifi->current_frame,"CC_mask %x is not full and frame has changed\n",ifi->CC_mask); AssertFatal(UL_info->frame != ifi->current_frame,"CC_mask %x is not full and frame has changed\n",ifi->CC_mask);
AssertFatal(UL_info->subframe != ifi->current_subframe,"CC_mask %x is not full and subframe has changed\n",ifi->CC_mask); AssertFatal(UL_info->slot != ifi->current_slot,"CC_mask %x is not full and slot has changed\n",ifi->CC_mask);
} }
ifi->CC_mask |= (1<<CC_id); ifi->CC_mask |= (1<<CC_id);
} }
// clear DL/UL info for new scheduling round // clear DL/UL info for new scheduling round
clear_nr_nfapi_information(RC.nrmac[module_id],CC_id,UL_info->frame,UL_info->subframe); clear_nr_nfapi_information(RC.nrmac[module_id],CC_id,UL_info->frame,UL_info->slot);
handle_nr_rach(UL_info); handle_nr_rach(UL_info);
...@@ -315,24 +315,24 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) ...@@ -315,24 +315,24 @@ void NR_UL_indication(NR_UL_IND_t *UL_info)
if (ifi->CC_mask == ((1<<MAX_NUM_CCs)-1)) { if (ifi->CC_mask == ((1<<MAX_NUM_CCs)-1)) {
/* /*
eNB_dlsch_ulsch_scheduler(module_id, eNB_dlsch_ulsch_scheduler(module_id,
(UL_info->frame+((UL_info->subframe>(9-sf_ahead))?1:0)) % 1024, (UL_info->frame+((UL_info->slot>(9-sf_ahead))?1:0)) % 1024,
(UL_info->subframe+sf_ahead)%10); (UL_info->slot+sf_ahead)%10);
*/ */
gNB_dlsch_ulsch_scheduler(module_id, gNB_dlsch_ulsch_scheduler(module_id,
(UL_info->frame+((UL_info->subframe>(9-sf_ahead))?1:0)) % 1024, (UL_info->frame+((UL_info->slot>(9-sf_ahead))?1:0)) % 1024,
(UL_info->subframe+sf_ahead)%10); (UL_info->slot+sf_ahead)%10);
ifi->CC_mask = 0; ifi->CC_mask = 0;
sched_info->module_id = module_id; sched_info->module_id = module_id;
sched_info->CC_id = CC_id; sched_info->CC_id = CC_id;
sched_info->frame = (UL_info->frame + ((UL_info->subframe>(9-sf_ahead)) ? 1 : 0)) % 1024; sched_info->frame = (UL_info->frame + ((UL_info->slot>(9-sf_ahead)) ? 1 : 0)) % 1024;
sched_info->subframe = (UL_info->subframe+sf_ahead)%10; sched_info->slot = (UL_info->slot+sf_ahead)%10;
sched_info->DL_req = &mac->DL_req[CC_id]; sched_info->DL_req = &mac->DL_req[CC_id];
sched_info->HI_DCI0_req = &mac->HI_DCI0_req[CC_id]; sched_info->HI_DCI0_req = &mac->HI_DCI0_req[CC_id];
if ((mac->common_channels[CC_id].tdd_Config==NULL) || if ((mac->common_channels[CC_id].tdd_Config==NULL) ||
(is_nr_UL_sf(&mac->common_channels[CC_id],(sched_info->subframe+sf_ahead)%10)>0)) (is_nr_UL_sf(&mac->common_channels[CC_id],(sched_info->slot+sf_ahead)%10)>0))
sched_info->UL_req = &mac->UL_req[CC_id]; sched_info->UL_req = &mac->UL_req[CC_id];
else else
sched_info->UL_req = NULL; sched_info->UL_req = NULL;
...@@ -352,7 +352,7 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) ...@@ -352,7 +352,7 @@ void NR_UL_indication(NR_UL_IND_t *UL_info)
ifi->NR_Schedule_response(sched_info); ifi->NR_Schedule_response(sched_info);
} }
LOG_D(PHY,"NR_Schedule_response: SFN_SF:%d%d dl_pdus:%d\n",sched_info->frame,sched_info->subframe,sched_info->DL_req->dl_config_request_body.number_pdu); LOG_D(PHY,"NR_Schedule_response: SFN_SF:%d%d dl_pdus:%d\n",sched_info->frame,sched_info->slot,sched_info->DL_req->dl_config_request_body.number_pdu);
} }
} }
} }
......
...@@ -57,8 +57,8 @@ typedef struct{ ...@@ -57,8 +57,8 @@ typedef struct{
int CC_id; int CC_id;
/// frame /// frame
frame_t frame; frame_t frame;
/// subframe /// slot
sub_frame_t subframe; slot_t slot;
/// harq indication list /// harq indication list
nfapi_harq_indication_t harq_ind; nfapi_harq_indication_t harq_ind;
...@@ -88,7 +88,7 @@ typedef struct{ ...@@ -88,7 +88,7 @@ typedef struct{
} NR_UL_IND_t; } NR_UL_IND_t;
// Downlink subframe P7 // Downlink slot P7
typedef struct{ typedef struct{
...@@ -98,8 +98,8 @@ typedef struct{ ...@@ -98,8 +98,8 @@ typedef struct{
uint8_t CC_id; uint8_t CC_id;
/// frame /// frame
frame_t frame; frame_t frame;
/// subframe /// slot
sub_frame_t subframe; slot_t slot;
/// nFAPI DL Config Request /// nFAPI DL Config Request
nfapi_nr_dl_config_request_t *DL_req; nfapi_nr_dl_config_request_t *DL_req;
/// nFAPI UL Config Request /// nFAPI UL Config Request
...@@ -123,7 +123,7 @@ typedef struct NR_IF_Module_s{ ...@@ -123,7 +123,7 @@ typedef struct NR_IF_Module_s{
void (*NR_PHY_config_req)(NR_PHY_Config_t* config_INFO); void (*NR_PHY_config_req)(NR_PHY_Config_t* config_INFO);
uint32_t CC_mask; uint32_t CC_mask;
uint16_t current_frame; uint16_t current_frame;
uint8_t current_subframe; uint8_t current_slot;
pthread_mutex_t if_mutex; pthread_mutex_t if_mutex;
} NR_IF_Module_t; } NR_IF_Module_t;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment