diff --git a/ci-scripts/conf_files/gnb.band261.tm1.32PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.band261.tm1.32PRB.usrpn300.conf
index 2bfd09509c..0da833b3f7 100644
--- a/ci-scripts/conf_files/gnb.band261.tm1.32PRB.usrpn300.conf
+++ b/ci-scripts/conf_files/gnb.band261.tm1.32PRB.usrpn300.conf
@@ -23,6 +23,7 @@ gNBs =
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1;
+ pusch_AntennaPorts = 1;
pusch_TargetSNRx10 = 200;
pucch_TargetSNRx10 = 200;
diff --git a/ci-scripts/conf_files/gnb.band66.tm1.106PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.band66.tm1.106PRB.usrpn300.conf
index fc32d65a23..b8a601ce41 100644
--- a/ci-scripts/conf_files/gnb.band66.tm1.106PRB.usrpn300.conf
+++ b/ci-scripts/conf_files/gnb.band66.tm1.106PRB.usrpn300.conf
@@ -23,6 +23,7 @@ gNBs =
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1;
+ pusch_AntennaPorts = 1;
servingCellConfigCommon = (
{
diff --git a/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf b/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf
index daee5486c1..7be25a24fa 100644
--- a/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf
+++ b/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf
@@ -22,6 +22,7 @@ gNBs =
ssb_SubcarrierOffset = 31; //0;
pdsch_AntennaPorts = 1;
+ pusch_AntennaPorts = 1;
pusch_TargetSNRx10 = 200;
pucch_TargetSNRx10 = 200;
@@ -250,7 +251,7 @@ L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
- pusch_proc_threads = 8;
+ pusch_proc_threads = 6;
}
);
diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml
index 016c76dc06..b0511f63cc 100644
--- a/cmake_targets/autotests/test_case_list.xml
+++ b/cmake_targets/autotests/test_case_list.xml
@@ -1330,7 +1330,8 @@
(Test3: 30kHz SCS, 273 PRBs, Prach format A2),
(Test4: 30kHz SCS, 106 PRBs, Prach format 0),
(Test5: 120kHz SCS, 32 PRBs, Prach format A2),
- (Test6: 120kHz SCS, 66 PRBs, Prach format A2)
+ (Test6: 120kHz SCS, 66 PRBs, Prach format A2),
+ (Test7: 120kHz SCS, 66 PRBs, High Speed Enabled)
$OPENAIR_DIR/cmake_targets/build_oai
--phy_simulators -c
@@ -1342,8 +1343,9 @@
-a -s -30 -n 100 -p 63 -R 273
-a -s -30 -n 100 -p 63 -R 106 -c 4
-a -s -30 -n 100 -p 32 -R 32 -m 3 -c52
- -a -s -30 -n 100 -p 32 -R 66 -m 3 -c52
- nr_prachsim.test1 nr_prachsim.test2 nr_prachsim.test3 nr_prachsim.test4 nr_prachsim.test5 nr_prachsim.test6
+ -a -s -30 -n 100 -p 32 -R 66 -m 3 -c52
+ -a -s -30 -n 100 -R 66 -m 3 -c52 -H
+ nr_prachsim.test1 nr_prachsim.test2 nr_prachsim.test3 nr_prachsim.test4 nr_prachsim.test5 nr_prachsim.test6 nr_prachsim.test7
PRACH test OK
segmentation fault|assertion|exiting|fatal
3
diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c
index 184a3a0e07..a92f433560 100644
--- a/executables/nr-gnb.c
+++ b/executables/nr-gnb.c
@@ -468,15 +468,14 @@ void init_gNB(int single_thread_flag,int wait_for_sync) {
PHY_VARS_gNB *gNB;
if (RC.gNB == NULL) {
- RC.gNB = (PHY_VARS_gNB **) malloc((1+RC.nb_nr_L1_inst)*sizeof(PHY_VARS_gNB *));
+ RC.gNB = (PHY_VARS_gNB **) calloc(1+RC.nb_nr_L1_inst, sizeof(PHY_VARS_gNB *));
LOG_I(PHY,"gNB L1 structure RC.gNB allocated @ %p\n",RC.gNB);
}
for (inst=0; instnumerology_index;
- uint8_t half_frame_index = fp->half_frame_bit;
- uint8_t i_ssb = fp->ssb_index;
int symbol = 0;
uint8_t n, n_temp;
nr_ssb_type_e type = fp->ssb_type;
@@ -69,9 +66,6 @@ int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp)
AssertFatal(0==1, "Invalid numerology index %d for the synchronization block\n", mu);
}
- if (half_frame_index)
- symbol += (5 * fp->symbols_per_slot * fp->slots_per_subframe);
-
return symbol;
}
diff --git a/openair1/PHY/INIT/phy_init.h b/openair1/PHY/INIT/phy_init.h
index 9c474264c8..2db0ccc258 100644
--- a/openair1/PHY/INIT/phy_init.h
+++ b/openair1/PHY/INIT/phy_init.h
@@ -392,7 +392,7 @@ void phy_config_update_sib13_request(PHY_Config_t *phy_config);
int init_frame_parms(LTE_DL_FRAME_PARMS *frame_parms,uint8_t osf);
void dump_frame_parms(LTE_DL_FRAME_PARMS *frame_parms);
-int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp);
+int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp,uint8_t i_ssb);
int nr_init_frame_parms(nfapi_nr_config_request_scf_t *config, NR_DL_FRAME_PARMS *frame_parms);
int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *frame_parms, fapi_nr_config_request_t *config, uint16_t nr_band);
int init_nr_ue_signal(PHY_VARS_NR_UE *ue,int nb_connected_eNB,uint8_t abstraction_flag);
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.c b/openair1/PHY/NR_TRANSPORT/nr_dci.c
index 32adb3276e..b7de182ab7 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dci.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dci.c
@@ -30,7 +30,7 @@
* \warning
*/
-#include
+
#include "nr_dci.h"
#include "nr_dlsch.h"
#include "nr_sch_dmrs.h"
diff --git a/openair1/PHY/NR_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_TRANSPORT/nr_pbch.c
index bd1278b2eb..0bc04e3047 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_pbch.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_pbch.c
@@ -241,7 +241,7 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch,
///Payload generation
memset((void *)pbch, 0, sizeof(NR_gNB_PBCH));
pbch->pbch_a=0;
- uint8_t ssb_index = frame_parms->ssb_index;
+ uint8_t ssb_index = ssb_pdu->ssb_pdu_rel15.SsbBlockIndex;
uint8_t *pbch_pdu = (uint8_t*)&ssb_pdu->ssb_pdu_rel15.bchPayload;
uint8_t Lmax = frame_parms->Lmax;
for (int i=0; issb_index += (((nr_ue_pbch_vars->xtra_byte>>(7-i))&0x01)<<(3+i));
}
- ue->symbol_offset = nr_get_ssb_start_symbol(frame_parms);
+ ue->symbol_offset = nr_get_ssb_start_symbol(frame_parms,i_ssb);
+ if (frame_parms->half_frame_bit)
+ ue->symbol_offset += (frame_parms->slots_per_frame>>1)*frame_parms->symbols_per_slot;
uint8_t frame_number_4lsb = 0;
for (int i=0; i<4; i++)
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c
index 0ba02c6bac..2c4c0b9e14 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c
@@ -130,6 +130,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
#endif
not_found = 1;
+ nr_fill_du(N_ZC,prach_root_sequence_map);
preamble_index0 = preamble_index;
// set preamble_offset to initial rootSequenceIndex and look if we need more root sequences for this
// preamble index and find the corresponding cyclic shift
diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h
index 0462da5e88..a165aa1984 100644
--- a/openair1/PHY/defs_gNB.h
+++ b/openair1/PHY/defs_gNB.h
@@ -182,7 +182,10 @@ typedef struct {
int16_t sqrt_rho_b;
} NR_gNB_DLSCH_t;
-
+typedef struct {
+ bool active;
+ nfapi_nr_dl_tti_ssb_pdu ssb_pdu;
+} NR_gNB_SSB_t;
typedef struct {
int frame;
@@ -712,10 +715,10 @@ typedef struct PHY_VARS_gNB_s {
// nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu;
// nfapi_nr_ul_dci_request_pdus_t *ul_dci_pdu;
- nfapi_nr_dl_tti_ssb_pdu ssb_pdu;
uint16_t num_pdsch_rnti[80];
- NR_gNB_PBCH pbch;
+ NR_gNB_SSB_t ssb[64];
+ NR_gNB_PBCH pbch;
nr_cce_t cce_list[MAX_DCI_CORESET][NR_MAX_PDCCH_AGG_LEVEL];
NR_gNB_COMMON common_vars;
NR_gNB_PRACH prach_vars;
diff --git a/openair1/SCHED_NR/fapi_nr_l1.c b/openair1/SCHED_NR/fapi_nr_l1.c
index d65d3b54bb..88f3dca070 100644
--- a/openair1/SCHED_NR/fapi_nr_l1.c
+++ b/openair1/SCHED_NR/fapi_nr_l1.c
@@ -50,8 +50,15 @@ void handle_nr_nfapi_ssb_pdu(PHY_VARS_gNB *gNB,int frame,int slot,
AssertFatal(dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.bchPayloadFlag== 1, "bchPayloadFlat %d != 1\n",
dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.bchPayloadFlag);
- LOG_D(PHY,"%d.%d : pbch_pdu: %x\n",frame,slot,dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.bchPayload);
- memcpy((void*)&gNB->ssb_pdu,&dl_tti_pdu->ssb_pdu,sizeof(dl_tti_pdu->ssb_pdu));
+ uint8_t i_ssb = dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.SsbBlockIndex;
+
+ LOG_D(PHY,"%d.%d : ssb index %d pbch_pdu: %x\n",frame,slot,i_ssb,dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.bchPayload);
+ if (gNB->ssb[i_ssb].active)
+ AssertFatal(1==0,"SSB PDU with index %d already active\n",i_ssb);
+ else {
+ gNB->ssb[i_ssb].active = true;
+ memcpy((void*)&gNB->ssb[i_ssb].ssb_pdu,&dl_tti_pdu->ssb_pdu,sizeof(dl_tti_pdu->ssb_pdu));
+ }
}
/*void handle_nr_nfapi_pdsch_pdu(PHY_VARS_gNB *gNB,int frame,int subframe,gNB_L1_rxtx_proc_t *proc,
@@ -166,14 +173,11 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){
gNB->dlsch[i][0]->harq_mask=0;
}
- gNB->pbch_configured=0;
-
for (int i=0;idl_tti_request_body.dl_tti_pdu_list[i];
LOG_D(PHY,"NFAPI: dl_pdu %d : type %d\n",i,dl_tti_pdu->PDUType);
switch (dl_tti_pdu->PDUType) {
case NFAPI_NR_DL_TTI_SSB_PDU_TYPE:
- gNB->pbch_configured=1;
if(NFAPI_MODE != NFAPI_MODE_VNF)
handle_nr_nfapi_ssb_pdu(gNB,frame,slot,
@@ -257,4 +261,4 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){
}
-}
\ No newline at end of file
+}
diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
index 674ae82cc3..d44c8641a6 100644
--- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c
+++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
@@ -67,85 +67,63 @@ void nr_set_ssb_first_subcarrier(nfapi_nr_config_request_scf_t *cfg, NR_DL_FRAME
LOG_D(PHY, "SSB first subcarrier %d (%d,%d)\n", fp->ssb_start_subcarrier,cfg->ssb_table.ssb_offset_point_a.value,sco);
}
-void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int slot) {
+void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame,int slot,nfapi_nr_dl_tti_ssb_pdu ssb_pdu) {
NR_DL_FRAME_PARMS *fp=&gNB->frame_parms;
nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
int **txdataF = gNB->common_vars.txdataF;
- uint8_t ssb_index, ssb_per_slot=0, n_hf;
- uint16_t ssb_start_symbol, rel_slot;
+ uint8_t ssb_index, n_hf;
+ uint16_t ssb_start_symbol;
int txdataF_offset = (slot%2)*fp->samples_per_slot_wCP;
uint16_t slots_per_hf = (fp->slots_per_frame)>>1;
- n_hf = fp->half_frame_bit;
+ if (slotssb_table.ssb_period.value == 0) {
- if (slotsymbols_per_slot; // start symbol wrt slot
+
+ nr_set_ssb_first_subcarrier(cfg, fp); // setting the first subcarrier
+
+ 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[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp);
+ nr_generate_sss(gNB->d_sss, &txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp);
+
+ if (cfg->carrier_config.num_tx_ant.value <= 4)
+ nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[n_hf][ssb_index&7],&txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp);
+ else
+ nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[0][ssb_index&7],&txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp);
+
+ if (T_ACTIVE(T_GNB_PHY_MIB)) {
+ unsigned char bch[3];
+ bch[0] = ssb_pdu.ssb_pdu_rel15.bchPayload & 0xff;
+ bch[1] = (ssb_pdu.ssb_pdu_rel15.bchPayload >> 8) & 0xff;
+ bch[2] = (ssb_pdu.ssb_pdu_rel15.bchPayload >> 16) & 0xff;
+ T(T_GNB_PHY_MIB, T_INT(0) /* module ID */, T_INT(frame), T_INT(slot), T_BUFFER(bch, 3));
}
- // to set a effective slot number in the half frame where the SSB is supposed to be
- rel_slot = (n_hf)? (slot-slots_per_hf) : slot;
-
- LOG_D(PHY,"common_signal_procedures: frame %d, slot %d\n",frame,slot);
-
- if(rel_slot<38 && rel_slot>=0) { // there is no SSB beyond slot 37
-
- for (int i=0; i<2; i++) { // max two SSB per slot
-
- ssb_index = i + SSB_Table[rel_slot]; // computing the ssb_index
-
- if ((ssb_index<64) && ((fp->L_ssb >> (63-ssb_index)) & 0x01)) { // generating the ssb only if the bit of L_ssb at current ssb index is 1
- ssb_per_slot++;
- fp->ssb_index = ssb_index;
- int ssb_start_symbol_abs = nr_get_ssb_start_symbol(fp); // computing the starting symbol for current ssb
- ssb_start_symbol = ssb_start_symbol_abs % fp->symbols_per_slot; // start symbol wrt slot
-
- nr_set_ssb_first_subcarrier(cfg, fp); // setting the first subcarrier
-
- 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[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp);
- nr_generate_sss(gNB->d_sss, &txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp);
-
- if (cfg->carrier_config.num_tx_ant.value <= 4)
- nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[n_hf][ssb_index&7],&txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp);
- else
- nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[0][ssb_index&7],&txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp);
-
- if (T_ACTIVE(T_GNB_PHY_MIB)) {
- unsigned char bch[3];
- bch[0] = gNB->ssb_pdu.ssb_pdu_rel15.bchPayload & 0xff;
- bch[1] = (gNB->ssb_pdu.ssb_pdu_rel15.bchPayload >> 8) & 0xff;
- bch[2] = (gNB->ssb_pdu.ssb_pdu_rel15.bchPayload >> 16) & 0xff;
- T(T_GNB_PHY_MIB, T_INT(0) /* module ID */, T_INT(frame), T_INT(slot), T_BUFFER(bch, 3));
- }
-
- nr_generate_pbch(&gNB->pbch,
- &gNB->ssb_pdu,
- gNB->nr_pbch_interleaver,
- &txdataF[0][txdataF_offset],
- AMP,
- ssb_start_symbol,
- n_hf, frame, cfg, fp);
-
- // SSB beamforming is handled at PHY
- // currently our PHY does not support switching more than once a slot.
- if (ssb_per_slot>1) {
- LOG_W(PHY,"beamforming currently not supported for more than one SSB per slot\n");
- }
- else if (ssb_per_slot==1) {
- LOG_D(PHY,"slot %d, ssb_index %d, beam %d\n",slot,ssb_index,cfg->ssb_table.ssb_beam_id_list[ssb_index].beam_id.value);
- for (int j=0;jsymbols_per_slot;j++)
- gNB->common_vars.beam_id[0][slot*fp->symbols_per_slot+j] = cfg->ssb_table.ssb_beam_id_list[ssb_index].beam_id.value;
- }
- }
- }
+ // Beam_id is currently used only for FR2
+ if (fp->freq_range==nr_FR2){
+ LOG_D(PHY,"slot %d, ssb_index %d, beam %d\n",slot,ssb_index,cfg->ssb_table.ssb_beam_id_list[ssb_index].beam_id.value);
+ for (int j=0;jsymbols_per_slot;j++)
+ gNB->common_vars.beam_id[0][slot*fp->symbols_per_slot+j] = cfg->ssb_table.ssb_beam_id_list[ssb_index].beam_id.value;
}
+
+ nr_generate_pbch(&gNB->pbch,
+ &ssb_pdu,
+ gNB->nr_pbch_interleaver,
+ &txdataF[0][txdataF_offset],
+ AMP,
+ ssb_start_symbol,
+ n_hf, frame, cfg, fp);
}
+
void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
int frame,int slot,
int do_meas) {
@@ -153,11 +131,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
NR_DL_FRAME_PARMS *fp=&gNB->frame_parms;
nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
int offset = gNB->CC_id;
- uint8_t ssb_frame_periodicity = 1; // every how many frames SSB are generated
int txdataF_offset = (slot%2)*fp->samples_per_slot_wCP;
-
- if (cfg->ssb_table.ssb_period.value > 1)
- ssb_frame_periodicity = 1 <<(cfg->ssb_table.ssb_period.value -1) ;
if ((cfg->cell_config.frame_duplex_type.value == TDD) &&
(nr_slot_select(cfg,frame,slot) == NR_UPLINK_SLOT)) return;
@@ -174,8 +148,12 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_COMMON_TX,1);
if (NFAPI_MODE == NFAPI_MONOLITHIC || NFAPI_MODE == NFAPI_MODE_PNF) {
- if ((!(frame%ssb_frame_periodicity))) // generate SSB only for given frames according to SSB periodicity
- nr_common_signal_procedures(gNB,frame, slot);
+ for (int i=0; iLmax; i++) {
+ if (gNB->ssb[i].active) {
+ nr_common_signal_procedures(gNB,frame,slot,gNB->ssb[i].ssb_pdu);
+ gNB->ssb[i].active = false;
+ }
+ }
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_COMMON_TX,0);
@@ -468,7 +446,7 @@ void fill_ul_rb_mask(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
(pucch->frame == frame_rx) &&
(pucch->slot == slot_rx) ) {
gNB->ulmask_symb = symbol;
- nfapi_nr_pucch_pdu_t *pucch_pdu = &pucch[i].pucch_pdu;
+ nfapi_nr_pucch_pdu_t *pucch_pdu = &pucch->pucch_pdu;
if ((symbol>=pucch_pdu->start_symbol_index) &&
(symbol<(pucch_pdu->start_symbol_index + pucch_pdu->nr_of_symbols))){
for (rb=0; rbprb_size; rb++) {
diff --git a/openair1/SCHED_NR/sched_nr.h b/openair1/SCHED_NR/sched_nr.h
index 24885f1bb4..e0cf20d862 100644
--- a/openair1/SCHED_NR/sched_nr.h
+++ b/openair1/SCHED_NR/sched_nr.h
@@ -40,7 +40,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, int frame_tx, int slot_tx, int do_
void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx);
void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx);
void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot);
-void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int slot);
+void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame,int slot,nfapi_nr_dl_tti_ssb_pdu ssb_pdu);
void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx);
void nr_feptx_ofdm_2thread(RU_t *ru,int frame_tx,int tti_tx);
void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa);
diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c
index 410ad67af0..3af2f410bc 100644
--- a/openair1/SIMULATION/NR_PHY/dlsim.c
+++ b/openair1/SIMULATION/NR_PHY/dlsim.c
@@ -176,6 +176,7 @@ int nr_derive_key(int alg_type, uint8_t alg_id,
}
void config_common(int Mod_idP,
+ int ssb_SubcarrierOffset,
int pdsch_AntennaPorts,
int pusch_AntennaPorts,
NR_ServingCellConfigCommon_t *scc
@@ -682,7 +683,7 @@ int main(int argc, char **argv)
NR_ServingCellConfig_t *scd = calloc(1,sizeof(NR_ServingCellConfig_t));
NR_CellGroupConfig_t *secondaryCellGroup=calloc(1,sizeof(*secondaryCellGroup));
prepare_scc(rrc.carrier.servingcellconfigcommon);
- uint64_t ssb_bitmap;
+ uint64_t ssb_bitmap = 1;
fill_scc(rrc.carrier.servingcellconfigcommon,&ssb_bitmap,N_RB_DL,N_RB_DL,mu,mu);
ssb_bitmap = 1;// Enable only first SSB with index ssb_indx=0
fix_scc(scc,ssb_bitmap);
@@ -861,7 +862,8 @@ int main(int argc, char **argv)
// generate signal
AssertFatal(input_fd==NULL,"Not ready for input signal file\n");
gNB->pbch_configured = 1;
- gNB->ssb_pdu.ssb_pdu_rel15.bchPayload=0x001234;
+ gNB->ssb[0].ssb_pdu.ssb_pdu_rel15.bchPayload=0x001234;
+ gNB->ssb[0].ssb_pdu.ssb_pdu_rel15.SsbBlockIndex = 0;
//Configure UE
rrc.carrier.MIB = (uint8_t*) malloc(4);
@@ -987,7 +989,7 @@ int main(int argc, char **argv)
printf("[DLSIM] PTRS Symbols in a slot: %2u, RE per Symbol: %3u, RE in a slot %4d\n", ptrsSymbPerSlot,ptrsRePerSymb, ptrsSymbPerSlot*ptrsRePerSymb );
}
if (run_initial_sync)
- nr_common_signal_procedures(gNB,frame,slot);
+ nr_common_signal_procedures(gNB,frame,slot,gNB->ssb[0].ssb_pdu);
else
phy_procedures_gNB_TX(gNB,frame,slot,0);
diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c
index a3c2501197..ee74909a9e 100644
--- a/openair1/SIMULATION/NR_PHY/pbchsim.c
+++ b/openair1/SIMULATION/NR_PHY/pbchsim.c
@@ -119,7 +119,7 @@ void nr_phy_config_request_sim_pbchsim(PHY_VARS_gNB *gNB,
int main(int argc, char **argv)
{
char c;
- int i,aa;//,l;
+ int i,aa,start_symbol;
double sigma2, sigma2_dB=10,SNR,snr0=-2.0,snr1=2.0;
double cfo=0;
uint8_t snr1set=0;
@@ -426,29 +426,28 @@ int main(int argc, char **argv)
switch (mu) {
case 1:
- scs = 30000;
- if (N_RB_DL == 217) {
- fs = 122.88e6;
- bw = 80e6;
-
- }
- else if (N_RB_DL == 245) {
- fs = 122.88e6;
- bw = 90e6;
- }
- else if (N_RB_DL == 273) {
- fs = 122.88e6;
- bw = 100e6;
- }
- else if (N_RB_DL == 106) {
- fs = 61.44e6;
- bw = 40e6;
- }
- else AssertFatal(1==0,"Unsupported numerology for mu %d, N_RB %d\n",mu, N_RB_DL);
- break;
-
-
+ scs = 30000;
+ frame_parms->Lmax = 8;
+ if (N_RB_DL == 217) {
+ fs = 122.88e6;
+ bw = 80e6;
+ }
+ else if (N_RB_DL == 245) {
+ fs = 122.88e6;
+ bw = 90e6;
+ }
+ else if (N_RB_DL == 273) {
+ fs = 122.88e6;
+ bw = 100e6;
+ }
+ else if (N_RB_DL == 106) {
+ fs = 61.44e6;
+ bw = 40e6;
+ }
+ else AssertFatal(1==0,"Unsupported numerology for mu %d, N_RB %d\n",mu, N_RB_DL);
+ break;
case 3:
+ frame_parms->Lmax = 64;
scs = 120000;
if (N_RB_DL == 66) {
fs = 122.88e6;
@@ -457,6 +456,7 @@ int main(int argc, char **argv)
else AssertFatal(1==0,"Unsupported numerology for mu %d, N_RB %d\n",mu, N_RB_DL);
break;
}
+
// cfo with respect to sub-carrier spacing
eps = cfo/scs;
@@ -510,7 +510,6 @@ int main(int argc, char **argv)
printf("Allocating %d samples for txdata\n",frame_length_complex_samples);
txdata[i] = malloc(frame_length_complex_samples*sizeof(int));
bzero(r_re[i],frame_length_complex_samples*sizeof(int));
-
}
if (pbch_file_fd!=NULL) {
@@ -536,60 +535,68 @@ int main(int argc, char **argv)
}
nr_gold_pbch(UE);
+
// generate signal
if (input_fd==NULL) {
- gNB->pbch_configured = 1;
-
- gNB->ssb_pdu.ssb_pdu_rel15.bchPayload = 0x55dd33;
- for (int slot=0;slotslots_per_frame;slot++) {
- for (aa=0; aaframe_parms.nb_antennas_tx; aa++)
- memset(gNB->common_vars.txdataF[aa],0,frame_parms->samples_per_slot_wCP*sizeof(int32_t));
-
- nr_common_signal_procedures (gNB,frame,slot);
+ for (i=0; iLmax; i++) {
+ if((SSB_positions >> i) & 0x01) {
- for (aa=0; aaframe_parms.nb_antennas_tx; aa++) {
- if (cyclic_prefix_type == 1) {
- PHY_ofdm_mod(gNB->common_vars.txdataF[aa],
- &txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)],
- frame_parms->ofdm_symbol_size,
- 12,
- frame_parms->nb_prefix_samples,
- CYCLIC_PREFIX);
- } else {
- /* nr_normal_prefix_mod(gNB->common_vars.txdataF[aa],
- &txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)],
- 14,
- frame_parms);*/
- PHY_ofdm_mod(gNB->common_vars.txdataF[aa],
- (int*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)],
- frame_parms->ofdm_symbol_size,
- 1,
- frame_parms->nb_prefix_samples0,
- CYCLIC_PREFIX);
-
- apply_nr_rotation(frame_parms,
- (int16_t*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)],
- slot,
- 0,
- 1,
- frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples0);
- PHY_ofdm_mod(&gNB->common_vars.txdataF[aa][frame_parms->ofdm_symbol_size],
- (int*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)+frame_parms->nb_prefix_samples0+frame_parms->ofdm_symbol_size],
- frame_parms->ofdm_symbol_size,
- 13,
- frame_parms->nb_prefix_samples,
- CYCLIC_PREFIX);
- apply_nr_rotation(frame_parms,
- (int16_t*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)+frame_parms->nb_prefix_samples0+frame_parms->ofdm_symbol_size],
- slot,
- 1,
- 13,
- frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples);
- }
- }
+ gNB->ssb[i].ssb_pdu.ssb_pdu_rel15.bchPayload = 0x55dd33;
+ gNB->ssb[i].ssb_pdu.ssb_pdu_rel15.SsbBlockIndex = i;
+
+ start_symbol = nr_get_ssb_start_symbol(frame_parms,i);
+ int slot = start_symbol/14;
+
+ for (aa=0; aaframe_parms.nb_antennas_tx; aa++)
+ memset(gNB->common_vars.txdataF[aa],0,frame_parms->samples_per_slot_wCP*sizeof(int32_t));
+
+ nr_common_signal_procedures (gNB,frame,slot,gNB->ssb[i].ssb_pdu);
+
+ for (aa=0; aaframe_parms.nb_antennas_tx; aa++) {
+ if (cyclic_prefix_type == 1) {
+ PHY_ofdm_mod(gNB->common_vars.txdataF[aa],
+ &txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)],
+ frame_parms->ofdm_symbol_size,
+ 12,
+ frame_parms->nb_prefix_samples,
+ CYCLIC_PREFIX);
+ } else {
+ /*nr_normal_prefix_mod(gNB->common_vars.txdataF[aa],
+ &txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)],
+ 14,
+ frame_parms);*/
+ PHY_ofdm_mod(gNB->common_vars.txdataF[aa],
+ (int*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)],
+ frame_parms->ofdm_symbol_size,
+ 1,
+ frame_parms->nb_prefix_samples0,
+ CYCLIC_PREFIX);
+
+ apply_nr_rotation(frame_parms,
+ (int16_t*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)],
+ slot,
+ 0,
+ 1,
+ frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples0);
+
+ PHY_ofdm_mod(&gNB->common_vars.txdataF[aa][frame_parms->ofdm_symbol_size],
+ (int*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)+frame_parms->nb_prefix_samples0+frame_parms->ofdm_symbol_size],
+ frame_parms->ofdm_symbol_size,
+ 13,
+ frame_parms->nb_prefix_samples,
+ CYCLIC_PREFIX);
+
+ apply_nr_rotation(frame_parms,
+ (int16_t*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)+frame_parms->nb_prefix_samples0+frame_parms->ofdm_symbol_size],
+ slot,
+ 1,
+ 13,
+ frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples);
+ }
+ }
+ }
}
-
LOG_M("txsigF0.m","txsF0", gNB->common_vars.txdataF[0],frame_length_complex_samples_no_prefix,1,1);
if (gNB->frame_parms.nb_antennas_tx>1)
LOG_M("txsigF1.m","txsF1", gNB->common_vars.txdataF[1],frame_length_complex_samples_no_prefix,1,1);
@@ -598,9 +605,9 @@ int main(int argc, char **argv)
printf("Reading %d samples from file to antenna buffer %d\n",frame_length_complex_samples,0);
UE->UE_fo_compensation = 1; // perform fo compensation when samples from file are used
if (fread(txdata[0],
- sizeof(int32_t),
- frame_length_complex_samples,
- input_fd) != frame_length_complex_samples) {
+ sizeof(int32_t),
+ frame_length_complex_samples,
+ input_fd) != frame_length_complex_samples) {
printf("error reading from file\n");
//exit(-1);
}
@@ -684,10 +691,9 @@ int main(int argc, char **argv)
UE->rx_offset=0;
uint8_t ssb_index = 0;
while (!((SSB_positions >> ssb_index) & 0x01)) ssb_index++; // to select the first transmitted ssb
- frame_parms->ssb_index = ssb_index;
- UE->symbol_offset = nr_get_ssb_start_symbol(frame_parms);
+ UE->symbol_offset = nr_get_ssb_start_symbol(frame_parms,ssb_index);
- int ssb_slot = (ssb_index>>1)+(n_hf*frame_parms->slots_per_frame);
+ int ssb_slot = (UE->symbol_offset/14)+(n_hf*(frame_parms->slots_per_frame>>1));
for (int i=UE->symbol_offset+1; isymbol_offset+4; i++) {
nr_slot_fep(UE,
&proc,
@@ -716,7 +722,7 @@ int main(int argc, char **argv)
payload_ret = (UE->pbch_vars[0]->xtra_byte == gNB_xtra_byte);
for (i=0;i<3;i++){
- payload_ret += (UE->pbch_vars[0]->decoded_output[i] == ((gNB->ssb_pdu.ssb_pdu_rel15.bchPayload>>(8*i)) & 0xff));
+ payload_ret += (UE->pbch_vars[0]->decoded_output[i] == ((gNB->ssb[ssb_index].ssb_pdu.ssb_pdu_rel15.bchPayload>>(8*i)) & 0xff));
}
//printf("xtra byte gNB: 0x%02x UE: 0x%02x\n",gNB_xtra_byte, UE->pbch_vars[0]->xtra_byte);
//printf("ret %d\n", payload_ret);
diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c
index fb5cdfa7d4..abe3cbf729 100644
--- a/openair1/SIMULATION/NR_PHY/prachsim.c
+++ b/openair1/SIMULATION/NR_PHY/prachsim.c
@@ -218,7 +218,7 @@ int main(int argc, char **argv){
randominit(0);
- while ((c = getopt (argc, argv, "hHaA:Cc:r:p:g:m:n:s:S:t:x:y:v:V:z:N:F:d:Z:L:R:E")) != -1) {
+ while ((c = getopt (argc, argv, "hHaA:Cc:l:r:p:g:m:n:s:S:t:x:y:v:V:z:N:F:d:Z:L:R:E")) != -1) {
switch (c) {
case 'a':
printf("Running AWGN simulation\n");
@@ -231,6 +231,10 @@ int main(int argc, char **argv){
config_index = atoi(optarg);
break;
+ case 'l':
+ loglvl = atoi(optarg);
+ break;
+
case 'r':
msg1_frequencystart = atoi(optarg);
break;
diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h
index 6b9060801d..ba12d9c5c3 100644
--- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h
+++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h
@@ -36,6 +36,7 @@
#include
#include
#include
+#include
#define TABLE_38213_13_1_NUM_INDEXES 15
#define TABLE_38213_13_2_NUM_INDEXES 14
@@ -418,14 +419,6 @@ typedef enum {
NR_RNTI_MCS_C,
} nr_rnti_type_t;
-typedef enum subcarrier_spacing_e {
- scs_15kHz = 0x1,
- scs_30kHz = 0x2,
- scs_60kHz = 0x4,
- scs_120kHz = 0x8,
- scs_240kHz = 0x16
-} subcarrier_spacing_t;
-
typedef enum channel_bandwidth_e {
bw_5MHz = 0x1,
bw_10MHz = 0x2,
@@ -462,6 +455,7 @@ typedef struct Type0_PDCCH_CSS_config_s {
uint32_t ssb_length;
uint32_t ssb_index;
uint32_t cset_start_rb;
+ bool active;
} NR_Type0_PDCCH_CSS_config_t;
#endif /*__LAYER2_MAC_H__ */
diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
index 20d8b917ce..eb309e66bf 100644
--- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
+++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
@@ -36,6 +36,13 @@
#define reserved 0xffff
+// start symbols for SSB types A,B,C,D,E
+uint16_t symbol_ssb_AC[8]={2,8,16,22,30,36,44,50};
+uint16_t symbol_ssb_BD[64]={4,8,16,20,32,36,44,48,60,64,72,76,88,92,100,104,144,148,156,160,172,176,184,188,200,204,212,216,228,232,240,244,284,288,
+ 296,300,312,316,324,328,340,344,352,356,368,372,380,384,424,428,436,440,452,456,464,468,480,484,492,496,508,512,520,524};
+uint16_t symbol_ssb_E[64]={8,12,16,20,32,36,40,44,64,68,72,76,88,92,96,100,120,124,128,132,144,148,152,156,176,180,184,188,200,204,208,212,288,292,
+ 296,300,312,316,320,324,344,348,352,356,368,372,376,380,400,404,408,412,424,428,432,436,456,460,464,468,480,484,488,492};
+
const uint8_t nr_slots_per_frame[5] = {10, 20, 40, 80, 160};
// Table 6.3.3.1-5 (38.211) NCS for preamble formats with delta_f_RA = 1.25 KHz
@@ -3158,56 +3165,58 @@ bool set_dl_ptrs_values(NR_PTRS_DownlinkConfig_t *ptrs_config,
return valid;
}
-uint32_t get_ssb_slot(uint32_t ssb_index){
- // this function now only support f <= 3GHz
- return ssb_index & 0x3 ;
+uint16_t get_ssb_start_symbol(const long band, NR_SubcarrierSpacing_t scs, int i_ssb) {
- // return first_symbol(case, freq, ssb_index) / 14
+ switch (scs) {
+ case NR_SubcarrierSpacing_kHz15:
+ return symbol_ssb_AC[i_ssb]; //type A
+ case NR_SubcarrierSpacing_kHz30:
+ if (band == 5 || band == 66)
+ return symbol_ssb_BD[i_ssb]; //type B
+ else
+ return symbol_ssb_AC[i_ssb]; //type C
+ case NR_SubcarrierSpacing_kHz120:
+ return symbol_ssb_BD[i_ssb]; //type D
+ case NR_SubcarrierSpacing_kHz240:
+ return symbol_ssb_E[i_ssb];
+ default:
+ AssertFatal(1 == 0, "SCS %ld not allowed for SSB \n",scs);
+ }
}
-int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config,
- NR_MIB_t *mib,
- uint8_t extra_bits,
- uint32_t ssb_length,
- uint32_t ssb_index,
- uint32_t ssb_offset_point_a) {
+void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config,
+ frame_t frameP,
+ NR_MIB_t *mib,
+ uint8_t num_slot_per_frame,
+ uint8_t ssb_subcarrier_offset,
+ uint16_t ssb_start_symbol,
+ NR_SubcarrierSpacing_t scs_ssb,
+ frequency_range_t frequency_range,
+ uint32_t ssb_index,
+ uint32_t ssb_offset_point_a) {
- // deafult for testing
- subcarrier_spacing_t scs_ssb = scs_30kHz;
- channel_bandwidth_t min_channel_bw = bw_10MHz;
- frequency_range_t frequency_range = FR1;
- const uint32_t num_slot_per_frame = 20;
+ NR_SubcarrierSpacing_t scs_pdcch;
+
+ channel_bandwidth_t min_channel_bw = bw_10MHz; // TODO remove hardcoding and implement Table 5.3.5-1 in 38.104
+
+ if (frequency_range == FR2) {
+ if(mib->subCarrierSpacingCommon == NR_MIB__subCarrierSpacingCommon_scs15or60)
+ scs_pdcch = NR_SubcarrierSpacing_kHz60;
+ else
+ scs_pdcch = NR_SubcarrierSpacing_kHz120;
+ }
+ else {
+ frequency_range = FR1;
+ if(mib->subCarrierSpacingCommon == NR_MIB__subCarrierSpacingCommon_scs15or60)
+ scs_pdcch = NR_SubcarrierSpacing_kHz15;
+ else
+ scs_pdcch = NR_SubcarrierSpacing_kHz30;
+ }
- type0_PDCCH_CSS_config->ssb_length = ssb_length;
type0_PDCCH_CSS_config->ssb_index = ssb_index;
- type0_PDCCH_CSS_config->frame = (mib->systemFrameNumber.buf[0] >> mib->systemFrameNumber.bits_unused);
+ type0_PDCCH_CSS_config->frame = frameP;
- uint16_t frame_number_4lsb = 0;
- for (int i=0; i<4; i++) {
- frame_number_4lsb |= ((extra_bits>>i)&1)<<(3-i);
- }
-
- uint8_t ssb_subcarrier_offset_msb = ( extra_bits >> 5 ) & 0x1; // extra bits[5]
- uint8_t ssb_subcarrier_offset = (uint8_t)mib->ssb_SubcarrierOffset;
-
- type0_PDCCH_CSS_config->frame = type0_PDCCH_CSS_config->frame << 4;
- type0_PDCCH_CSS_config->frame = type0_PDCCH_CSS_config->frame | frame_number_4lsb;
-
- if(type0_PDCCH_CSS_config->ssb_length == 64){
- type0_PDCCH_CSS_config->ssb_index = type0_PDCCH_CSS_config->ssb_index & (( extra_bits >> 2 ) & 0x1C ); // { extra_bits[5:7], ssb_index[2:0] }
- }else{
- if(ssb_subcarrier_offset_msb){
- ssb_subcarrier_offset = ssb_subcarrier_offset | 0x10;
- }
- }
-
- // assume carrier frequency < 6GHz
- subcarrier_spacing_t scs_pdcch;
- if(mib->subCarrierSpacingCommon == NR_MIB__subCarrierSpacingCommon_scs15or60){
- scs_pdcch = scs_15kHz;
- }else{ //NR_MIB__subCarrierSpacingCommon_scs30or120
- scs_pdcch = scs_30kHz;
- }
+ uint8_t ssb_slot = ssb_start_symbol/14;
uint32_t is_condition_A = (ssb_subcarrier_offset == 0); // 38.213 ch.13
uint32_t index_4msb = (mib->pdcch_ConfigSIB1.controlResourceSetZero);
@@ -3218,8 +3227,8 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
type0_PDCCH_CSS_config->rb_offset = -1;
// type0-pdcch coreset
- switch( (scs_ssb << 5) | scs_pdcch ){
- case (scs_15kHz << 5) | scs_15kHz :
+ switch( (scs_ssb << 3) | scs_pdcch ){
+ case (NR_SubcarrierSpacing_kHz15 << 5) | NR_SubcarrierSpacing_kHz15:
AssertFatal(index_4msb < 15, "38.213 Table 13-1 4 MSB out of range\n");
type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1;
type0_PDCCH_CSS_config->num_rbs = table_38213_13_1_c2[index_4msb];
@@ -3227,7 +3236,7 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
type0_PDCCH_CSS_config->rb_offset = table_38213_13_1_c4[index_4msb];
break;
- case (scs_15kHz << 5) | scs_30kHz:
+ case (NR_SubcarrierSpacing_kHz15 << 3) | NR_SubcarrierSpacing_kHz30:
AssertFatal(index_4msb < 14, "38.213 Table 13-2 4 MSB out of range\n");
type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1;
type0_PDCCH_CSS_config->num_rbs = table_38213_13_2_c2[index_4msb];
@@ -3235,7 +3244,7 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
type0_PDCCH_CSS_config->rb_offset = table_38213_13_2_c4[index_4msb];
break;
- case (scs_30kHz << 5) | scs_15kHz:
+ case (NR_SubcarrierSpacing_kHz30 << 3) | NR_SubcarrierSpacing_kHz15:
if((min_channel_bw & bw_5MHz) | (min_channel_bw & bw_10MHz)){
AssertFatal(index_4msb < 9, "38.213 Table 13-3 4 MSB out of range\n");
type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1;
@@ -3252,7 +3261,7 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
break;
- case (scs_30kHz << 5) | scs_30kHz:
+ case (NR_SubcarrierSpacing_kHz30 << 3) | NR_SubcarrierSpacing_kHz30:
if((min_channel_bw & bw_5MHz) | (min_channel_bw & bw_10MHz)){
type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1;
type0_PDCCH_CSS_config->num_rbs = table_38213_13_4_c2[index_4msb];
@@ -3268,7 +3277,7 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
}else{ ; }
break;
- case (scs_120kHz << 5) | scs_60kHz:
+ case (NR_SubcarrierSpacing_kHz120 << 3) | NR_SubcarrierSpacing_kHz60:
AssertFatal(index_4msb < 12, "38.213 Table 13-7 4 MSB out of range\n");
if(index_4msb & 0x7){
type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1;
@@ -3285,7 +3294,7 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
}
break;
- case (scs_120kHz << 5) | scs_120kHz:
+ case (NR_SubcarrierSpacing_kHz120 << 3) | NR_SubcarrierSpacing_kHz120:
AssertFatal(index_4msb < 8, "38.213 Table 13-8 4 MSB out of range\n");
if(index_4msb & 0x3){
type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1;
@@ -3302,7 +3311,7 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
}
break;
- case (scs_240kHz << 5) | scs_60kHz:
+ case (NR_SubcarrierSpacing_kHz240 << 3) | NR_SubcarrierSpacing_kHz60:
AssertFatal(index_4msb < 4, "38.213 Table 13-9 4 MSB out of range\n");
type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1;
type0_PDCCH_CSS_config->num_rbs = table_38213_13_9_c2[index_4msb];
@@ -3310,7 +3319,7 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
type0_PDCCH_CSS_config->rb_offset = table_38213_13_9_c4[index_4msb];
break;
- case (scs_240kHz << 5) | scs_120kHz:
+ case (NR_SubcarrierSpacing_kHz240 << 3) | NR_SubcarrierSpacing_kHz120:
AssertFatal(index_4msb < 8, "38.213 Table 13-10 4 MSB out of range\n");
if(index_4msb & 0x3){
type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1;
@@ -3381,7 +3390,7 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
type0_PDCCH_CSS_config->number_of_search_space_per_slot = table_38213_13_11_c2[index_4lsb];
big_m = table_38213_13_11_c3[index_4lsb];
- uint32_t temp = (uint32_t)(big_o*scs_pdcch) + (uint32_t)(type0_PDCCH_CSS_config->ssb_index*big_m);
+ uint32_t temp = (uint32_t)(big_o*(1<ssb_index*big_m);
type0_PDCCH_CSS_config->n_c = temp / num_slot_per_frame;
if((temp/num_slot_per_frame) & 0x1){
type0_PDCCH_CSS_config->sfn_c = SFN_C_MOD_2_EQ_1;
@@ -3417,12 +3426,12 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
/// MUX PATTERN 2
if(type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern == 2){
- if((scs_ssb == scs_120kHz) && (scs_pdcch == scs_60kHz)){
+ if((scs_ssb == NR_SubcarrierSpacing_kHz120) && (scs_pdcch == NR_SubcarrierSpacing_kHz60)){
// 38.213 Table 13-13
AssertFatal(index_4lsb == 0, "38.213 Table 13-13 4 LSB out of range\n");
// PDCCH monitoring occasions (SFN and slot number) same as SSB frame-slot
// sfn_c = SFN_C_EQ_SFN_SSB;
- type0_PDCCH_CSS_config->n_c = get_ssb_slot(type0_PDCCH_CSS_config->ssb_index);
+ type0_PDCCH_CSS_config->n_c = ssb_slot;
switch(type0_PDCCH_CSS_config->ssb_index & 0x3){ // ssb_index(i) mod 4
case 0:
type0_PDCCH_CSS_config->first_symbol_index = 0;
@@ -3439,12 +3448,12 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
default: break;
}
- }else if((scs_ssb == scs_240kHz) && (scs_pdcch == scs_120kHz)){
+ }else if((scs_ssb == NR_SubcarrierSpacing_kHz240) && (scs_pdcch == NR_SubcarrierSpacing_kHz120)){
// 38.213 Table 13-14
AssertFatal(index_4lsb == 0, "38.213 Table 13-14 4 LSB out of range\n");
// PDCCH monitoring occasions (SFN and slot number) same as SSB frame-slot
// sfn_c = SFN_C_EQ_SFN_SSB;
- type0_PDCCH_CSS_config->n_c = get_ssb_slot(type0_PDCCH_CSS_config->ssb_index);
+ type0_PDCCH_CSS_config->n_c = ssb_slot;
switch(type0_PDCCH_CSS_config->ssb_index & 0x7){ // ssb_index(i) mod 8
case 0:
type0_PDCCH_CSS_config->first_symbol_index = 0;
@@ -3460,11 +3469,11 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
break;
case 4:
type0_PDCCH_CSS_config->first_symbol_index = 12;
- type0_PDCCH_CSS_config->n_c = get_ssb_slot(type0_PDCCH_CSS_config->ssb_index) - 1;
+ type0_PDCCH_CSS_config->n_c = ssb_slot - 1;
break;
case 5:
type0_PDCCH_CSS_config->first_symbol_index = 13;
- type0_PDCCH_CSS_config->n_c = get_ssb_slot(type0_PDCCH_CSS_config->ssb_index) - 1;
+ type0_PDCCH_CSS_config->n_c = ssb_slot - 1;
break;
case 6:
type0_PDCCH_CSS_config->first_symbol_index = 0;
@@ -3481,12 +3490,12 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
/// MUX PATTERN 3
if(type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern == 3){
- if((scs_ssb == scs_120kHz) && (scs_pdcch == scs_120kHz)){
+ if((scs_ssb == NR_SubcarrierSpacing_kHz120) && (scs_pdcch == NR_SubcarrierSpacing_kHz120)){
// 38.213 Table 13-15
AssertFatal(index_4lsb == 0, "38.213 Table 13-15 4 LSB out of range\n");
// PDCCH monitoring occasions (SFN and slot number) same as SSB frame-slot
// sfn_c = SFN_C_EQ_SFN_SSB;
- type0_PDCCH_CSS_config->n_c = get_ssb_slot(type0_PDCCH_CSS_config->ssb_index);
+ type0_PDCCH_CSS_config->n_c = ssb_slot;
switch(type0_PDCCH_CSS_config->ssb_index & 0x3){ // ssb_index(i) mod 4
case 0:
type0_PDCCH_CSS_config->first_symbol_index = 4;
@@ -3523,10 +3532,9 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
AssertFatal(type0_PDCCH_CSS_config->sfn_c!=SFN_C_IMPOSSIBLE,"");
AssertFatal(type0_PDCCH_CSS_config->n_c!=UINT_MAX,"");
- type0_PDCCH_CSS_config->n_0 = ((uint32_t)(big_o*scs_pdcch) + (uint32_t)(type0_PDCCH_CSS_config->ssb_index*big_m))%num_slot_per_frame;
+ type0_PDCCH_CSS_config->n_0 = ((uint32_t)(big_o*(1<ssb_index*big_m))%num_slot_per_frame;
type0_PDCCH_CSS_config->cset_start_rb = ssb_offset_point_a - type0_PDCCH_CSS_config->rb_offset;
- return 0;
}
/* extract UL PTRS values from RRC and validate it based upon 38.214 6.2.3 */
diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h
index 103c4f5733..f766f7bcc7 100644
--- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h
+++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h
@@ -126,12 +126,18 @@ int32_t get_l_prime(uint8_t duration_in_symbols, uint8_t mapping_type, pusch_dmr
uint8_t get_L_ptrs(uint8_t mcs1, uint8_t mcs2, uint8_t mcs3, uint8_t I_mcs, uint8_t mcs_table);
uint8_t get_K_ptrs(uint16_t nrb0, uint16_t nrb1, uint16_t N_RB);
-int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config,
- NR_MIB_t *mib,
- uint8_t extra_bits,
- uint32_t ssb_length,
- uint32_t ssb_index,
- uint32_t ssb_offset_point_a);
+void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config,
+ frame_t frameP,
+ NR_MIB_t *mib,
+ uint8_t num_slot_per_frame,
+ uint8_t ssb_subcarrier_offset,
+ uint16_t ssb_start_symbol,
+ NR_SubcarrierSpacing_t scs_ssb,
+ frequency_range_t frequency_range,
+ uint32_t ssb_index,
+ uint32_t ssb_offset_point_a);
+
+uint16_t get_ssb_start_symbol(const long band, NR_SubcarrierSpacing_t scs, int i_ssb);
int16_t get_N_RA_RB (int delta_f_RA_PRACH,int delta_f_PUSCH);
diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h
index 5821c11816..098814498e 100755
--- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h
+++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h
@@ -325,7 +325,7 @@ typedef struct {
NR_TAG_Config_t *tag_Config;
NR_PHR_Config_t *phr_Config;
NR_RNTI_Value_t *cs_RNTI;
- NR_MIB_t *mib;
+ NR_MIB_t *mib;
NR_BWP_Downlink_t *DLbwp[MAX_NUM_BWP];
NR_BWP_Uplink_t *ULbwp[MAX_NUM_BWP];
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
index ec36486f70..719fd5ea61 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
@@ -104,7 +104,8 @@ int8_t nr_ue_decode_mib(module_id_t module_id,
LOG_D(MAC,"[L2][MAC] decode mib\n");
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
-
+ NR_ServingCellConfigCommon_t *scc = mac->scc;
+ frequency_range_t frequency_range;
nr_mac_rrc_data_ind_ue( module_id, cc_id, gNB_index, 0, 0, 0, NR_BCCH_BCH, (uint8_t *) pduP, 3 ); // fixed 3 bytes MIB PDU
AssertFatal(mac->mib != NULL, "nr_ue_decode_mib() mac->mib == NULL\n");
@@ -120,9 +121,11 @@ int8_t nr_ue_decode_mib(module_id_t module_id,
frame = frame << 4;
frame = frame | frame_number_4lsb;
if(ssb_length == 64){
+ frequency_range = FR2;
for (int i=0; i<3; i++)
ssb_index += (((extra_bits>>(7-i))&0x01)<<(3+i));
}else{
+ frequency_range = FR1;
if(ssb_subcarrier_offset_msb){
ssb_subcarrier_offset = ssb_subcarrier_offset | 0x10;
}
@@ -141,13 +144,37 @@ int8_t nr_ue_decode_mib(module_id_t module_id,
//storing ssb index in the mac structure
mac->mib_ssb = ssb_index;
- get_type0_PDCCH_CSS_config_parameters(&mac->type0_PDCCH_CSS_config, mac->mib, extra_bits, ssb_length, ssb_index,
- mac->phy_config.config_req.ssb_table.ssb_offset_point_a);
+ if (get_softmodem_params()->sa == 1) {
+
+ // TODO these values shouldn't be taken from SCC in SA
+ uint8_t scs_ssb = *scc->ssbSubcarrierSpacing;
+ uint32_t band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
+ int scs_scaling = 1<downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA < 600000)
+ scs_scaling = scs_scaling*3;
+ if (scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA > 2016666)
+ scs_scaling = scs_scaling>>2;
+ uint32_t absolute_diff = (*scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB - scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA);
+
+ uint16_t ssb_start_symbol = get_ssb_start_symbol(band,scs_ssb,ssb_index);
+
+ get_type0_PDCCH_CSS_config_parameters(&mac->type0_PDCCH_CSS_config,
+ frame,
+ mac->mib,
+ nr_slots_per_frame[scs_ssb],
+ ssb_subcarrier_offset,
+ ssb_start_symbol,
+ scs_ssb,
+ frequency_range,
+ ssb_index,
+ absolute_diff/(12*scs_scaling)-10);
+
+
+ mac->type0_pdcch_ss_mux_pattern = mac->type0_PDCCH_CSS_config.type0_pdcch_ss_mux_pattern;
+ mac->type0_pdcch_ss_sfn_c = mac->type0_PDCCH_CSS_config.sfn_c;
+ mac->type0_pdcch_ss_n_c = mac->type0_PDCCH_CSS_config.n_c;
+ }
- ssb_index = mac->type0_PDCCH_CSS_config.ssb_index; // TODO: ssb_index should obtain from L1 in case Lssb != 64
- mac->type0_pdcch_ss_mux_pattern = mac->type0_PDCCH_CSS_config.type0_pdcch_ss_mux_pattern;
- mac->type0_pdcch_ss_sfn_c = mac->type0_PDCCH_CSS_config.sfn_c;
- mac->type0_pdcch_ss_n_c = mac->type0_PDCCH_CSS_config.n_c;
mac->dl_config_request.sfn = mac->type0_PDCCH_CSS_config.frame;
mac->dl_config_request.slot = (ssb_index>>1) + ((ssb_index>>4)<<1); // not valid for 240kHz SCS
diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c
index 5974404fcd..d4bcc2adbc 100644
--- a/openair2/LAYER2/NR_MAC_gNB/config.c
+++ b/openair2/LAYER2/NR_MAC_gNB/config.c
@@ -54,7 +54,7 @@ extern RAN_CONTEXT_t RC;
extern void mac_top_init_gNB(void);
extern uint8_t nfapi_mode;
-void config_common(int Mod_idP, int pdsch_AntennaPorts, int pusch_AntennaPorts, NR_ServingCellConfigCommon_t *scc) {
+void config_common(int Mod_idP, int ssb_SubcarrierOffset, int pdsch_AntennaPorts, int pusch_AntennaPorts, NR_ServingCellConfigCommon_t *scc) {
nfapi_nr_config_request_scf_t *cfg = &RC.nrmac[Mod_idP]->config[0];
RC.nrmac[Mod_idP]->common_channels[0].ServingCellConfigCommon = scc;
@@ -244,6 +244,9 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, int pusch_AntennaPorts,
cfg->ssb_table.ssb_period.value = *scc->ssb_periodicityServingCell;
cfg->ssb_table.ssb_period.tl.tag = NFAPI_NR_CONFIG_SSB_PERIOD_TAG;
cfg->num_tlv++;
+ cfg->ssb_table.ssb_subcarrier_offset.value = ssb_SubcarrierOffset;
+ cfg->ssb_table.ssb_subcarrier_offset.tl.tag = NFAPI_NR_CONFIG_SSB_SUBCARRIER_OFFSET_TAG;
+ cfg->num_tlv++;
switch (scc->ssb_PositionsInBurst->present) {
case 1 :
@@ -380,6 +383,7 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
LOG_I(MAC,"Configuring common parameters from NR ServingCellConfig\n");
config_common(Mod_idP,
+ ssb_SubcarrierOffset,
pdsch_AntennaPorts,
pusch_AntennaPorts,
scc);
@@ -393,7 +397,8 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
printf("Waiting for PHY_config_req\n");
}
}
-
+
+ RC.nrmac[Mod_idP]->ssb_SubcarrierOffset = ssb_SubcarrierOffset;
RC.nrmac[Mod_idP]->pusch_target_snrx10 = pusch_tgt_snrx10;
RC.nrmac[Mod_idP]->pucch_target_snrx10 = pucch_tgt_snrx10;
NR_PHY_Config_t phycfg;
@@ -401,10 +406,6 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
phycfg.CC_id = 0;
phycfg.cfg = &RC.nrmac[Mod_idP]->config[0];
- phycfg.cfg->ssb_table.ssb_subcarrier_offset.value = ssb_SubcarrierOffset;
- phycfg.cfg->ssb_table.ssb_subcarrier_offset.tl.tag = NFAPI_NR_CONFIG_SSB_SUBCARRIER_OFFSET_TAG;
- phycfg.cfg->num_tlv++;
-
if (RC.nrmac[Mod_idP]->if_inst->NR_PHY_config_req) RC.nrmac[Mod_idP]->if_inst->NR_PHY_config_req(&phycfg);
find_SSB_and_RO_available(Mod_idP);
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c
index 49cfcbaf93..7d12536f9a 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c
@@ -53,35 +53,12 @@
#include "executables/softmodem-common.h"
extern RAN_CONTEXT_t RC;
-uint8_t SSB_Slot[64]={0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,
- 10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,17,
- 20,20,21,21,22,22,23,23,24,24,25,25,26,26,27,27,
- 30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37};
-void schedule_nr_mib(module_id_t module_idP,
- frame_t frameP,
- sub_frame_t slotP,
- uint8_t slots_per_frame,
- int nb_periods_per_frame){
- gNB_MAC_INST *gNB = RC.nrmac[module_idP];
- NR_COMMON_channels_t *cc;
-
- nfapi_nr_dl_tti_request_t *dl_tti_request;
- nfapi_nr_dl_tti_request_body_t *dl_req;
- nfapi_nr_dl_tti_request_pdu_t *dl_config_pdu;
+uint16_t get_ssboffset_pointa(NR_ServingCellConfigCommon_t *scc,const long band) {
- int mib_sdu_length;
- int CC_id;
- uint8_t beam_index = 0;
-
- for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
- cc = &gNB->common_channels[CC_id];
- NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
- const long band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
- const uint32_t ssb_offset0 = *scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB - scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA;
- int ratio;
- switch (*scc->ssbSubcarrierSpacing) {
+ int ratio;
+ switch (*scc->ssbSubcarrierSpacing) {
case NR_SubcarrierSpacing_kHz15:
AssertFatal(band <= 79,
"Band %ld is not possible for SSB with 15 kHz SCS\n",
@@ -115,146 +92,197 @@ void schedule_nr_mib(module_id_t module_idP,
default:
AssertFatal(1 == 0, "SCS %ld not allowed for SSB \n",
*scc->ssbSubcarrierSpacing);
- }
+ }
- // scheduling MIB every 8 frames, PHY repeats it in between
+ const uint32_t ssb_offset0 = *scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB - scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA;
+
+ return (ssb_offset0/(ratio*12) - 10); // absoluteFrequencySSB is the center of SSB
+
+}
+
+
+void schedule_ssb(frame_t frame, sub_frame_t slot,
+ NR_ServingCellConfigCommon_t *scc,
+ nfapi_nr_dl_tti_request_body_t *dl_req,
+ int i_ssb, uint8_t scoffset, uint16_t offset_pointa, uint32_t payload) {
+
+ uint8_t beam_index = 0;
+ nfapi_nr_dl_tti_request_pdu_t *dl_config_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
+ memset((void *) dl_config_pdu, 0,sizeof(nfapi_nr_dl_tti_request_pdu_t));
+ dl_config_pdu->PDUType = NFAPI_NR_DL_TTI_SSB_PDU_TYPE;
+ dl_config_pdu->PDUSize =2 + sizeof(nfapi_nr_dl_tti_ssb_pdu_rel15_t);
+
+ AssertFatal(scc->physCellId!=NULL,"ServingCellConfigCommon->physCellId is null\n");
+ dl_config_pdu->ssb_pdu.ssb_pdu_rel15.PhysCellId = *scc->physCellId;
+ dl_config_pdu->ssb_pdu.ssb_pdu_rel15.BetaPss = 0;
+ dl_config_pdu->ssb_pdu.ssb_pdu_rel15.SsbBlockIndex = i_ssb;
+ AssertFatal(scc->downlinkConfigCommon!=NULL,"scc->downlinkConfigCommonL is null\n");
+ AssertFatal(scc->downlinkConfigCommon->frequencyInfoDL!=NULL,"scc->downlinkConfigCommon->frequencyInfoDL is null\n");
+ AssertFatal(scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB!=NULL,"scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB is null\n");
+ AssertFatal(scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.count==1,"Frequency Band list does not have 1 element (%d)\n",
+ scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.count);
+ AssertFatal(scc->ssbSubcarrierSpacing,"ssbSubcarrierSpacing is null\n");
+ AssertFatal(scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0],"band is null\n");
+
+ dl_config_pdu->ssb_pdu.ssb_pdu_rel15.SsbSubcarrierOffset = scoffset; //kSSB
+ dl_config_pdu->ssb_pdu.ssb_pdu_rel15.ssbOffsetPointA = offset_pointa;
+ dl_config_pdu->ssb_pdu.ssb_pdu_rel15.bchPayloadFlag = 1;
+ dl_config_pdu->ssb_pdu.ssb_pdu_rel15.bchPayload = payload;
+ dl_config_pdu->ssb_pdu.ssb_pdu_rel15.precoding_and_beamforming.num_prgs=1;
+ dl_config_pdu->ssb_pdu.ssb_pdu_rel15.precoding_and_beamforming.prg_size=275; //1 PRG of max size for analogue beamforming
+ dl_config_pdu->ssb_pdu.ssb_pdu_rel15.precoding_and_beamforming.dig_bf_interfaces=1;
+ dl_config_pdu->ssb_pdu.ssb_pdu_rel15.precoding_and_beamforming.prgs_list[0].pm_idx = 0;
+ dl_config_pdu->ssb_pdu.ssb_pdu_rel15.precoding_and_beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = beam_index;
+ dl_req->nPDUs++;
+
+ LOG_D(MAC,"Scheduling ssb %d at frame %d and slot %d\n",i_ssb,frame,slot);
+
+}
+
+void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP, uint8_t slots_per_frame, int nb_periods_per_frame){
+
+ gNB_MAC_INST *gNB = RC.nrmac[module_idP];
+ NR_COMMON_channels_t *cc;
+ nfapi_nr_dl_tti_request_t *dl_tti_request;
+ nfapi_nr_dl_tti_request_body_t *dl_req;
+ NR_MIB_t *mib = RC.nrrrc[module_idP]->carrier.mib.message.choice.mib;
+ uint8_t num_tdd_period,num_ssb;
+ int mib_sdu_length;
+ int CC_id;
+
+ for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
+ cc = &gNB->common_channels[CC_id];
+ NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
+ dl_tti_request = &gNB->DL_req[CC_id];
+ dl_req = &dl_tti_request->dl_tti_request_body;
+
+ // get MIB every 8 frames
if((slotP == 0) && (frameP & 7) == 0) {
- dl_tti_request = &gNB->DL_req[CC_id];
- dl_req = &dl_tti_request->dl_tti_request_body;
- mib_sdu_length = mac_rrc_nr_data_req(module_idP, CC_id, frameP, MIBCH, 0, 1, &cc->MIB_pdu.payload[0]);
-
- LOG_D(MAC, "Frame %d, slot %d: BCH PDU length %d\n", frameP, slotP, mib_sdu_length);
-
- if (mib_sdu_length > 0) {
- LOG_D(MAC,
- "Frame %d, slot %d: Adding BCH PDU in position %d (length %d)\n",
- frameP,
- slotP,
- dl_req->nPDUs,
- mib_sdu_length);
-
- if ((frameP & 1023) < 80){
- LOG_D(MAC,
- "[gNB %d] Frame %d : MIB->BCH CC_id %d, Received %d bytes\n",
- module_idP,
- frameP,
- CC_id,
- mib_sdu_length);
- }
-
- dl_config_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
- memset((void *) dl_config_pdu, 0,sizeof(nfapi_nr_dl_tti_request_pdu_t));
- dl_config_pdu->PDUType = NFAPI_NR_DL_TTI_SSB_PDU_TYPE;
- dl_config_pdu->PDUSize =2 + sizeof(nfapi_nr_dl_tti_ssb_pdu_rel15_t);
-
- AssertFatal(scc->physCellId!=NULL,"scc->physCellId is null\n");
- dl_config_pdu->ssb_pdu.ssb_pdu_rel15.PhysCellId = *scc->physCellId;
- dl_config_pdu->ssb_pdu.ssb_pdu_rel15.BetaPss = 0;
- dl_config_pdu->ssb_pdu.ssb_pdu_rel15.SsbBlockIndex = 0;
- AssertFatal(scc->downlinkConfigCommon!=NULL,"scc->downlinkConfigCommonL is null\n");
- AssertFatal(scc->downlinkConfigCommon->frequencyInfoDL!=NULL,"scc->downlinkConfigCommon->frequencyInfoDL is null\n");
- AssertFatal(scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB!=NULL,"scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB is null\n");
- AssertFatal(scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.count==1,"Frequency Band list does not have 1 element (%d)\n",
- scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.count);
- AssertFatal(scc->ssbSubcarrierSpacing,"ssbSubcarrierSpacing is null\n");
- AssertFatal(scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0],"band is null\n");
-
- const nfapi_nr_config_request_scf_t *cfg = &RC.nrmac[module_idP]->config[0];
- dl_config_pdu->ssb_pdu.ssb_pdu_rel15.SsbSubcarrierOffset = cfg->ssb_table.ssb_subcarrier_offset.value; //kSSB
- dl_config_pdu->ssb_pdu.ssb_pdu_rel15.ssbOffsetPointA = ssb_offset0/(ratio*12) - 10; // absoluteFrequencySSB is the center of SSB
- dl_config_pdu->ssb_pdu.ssb_pdu_rel15.bchPayloadFlag = 1;
- dl_config_pdu->ssb_pdu.ssb_pdu_rel15.bchPayload = (*(uint32_t*)cc->MIB_pdu.payload) & ((1<<24)-1);
- dl_config_pdu->ssb_pdu.ssb_pdu_rel15.precoding_and_beamforming.num_prgs=1;
- dl_config_pdu->ssb_pdu.ssb_pdu_rel15.precoding_and_beamforming.prg_size=275; //1 PRG of max size for analogue beamforming
- dl_config_pdu->ssb_pdu.ssb_pdu_rel15.precoding_and_beamforming.dig_bf_interfaces=1;
- dl_config_pdu->ssb_pdu.ssb_pdu_rel15.precoding_and_beamforming.prgs_list[0].pm_idx = 0;
- dl_config_pdu->ssb_pdu.ssb_pdu_rel15.precoding_and_beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = beam_index;
- dl_req->nPDUs++;
- }
-
- // Get type0_PDCCH_CSS_config parameters
- NR_DL_FRAME_PARMS *frame_parms = &RC.gNB[module_idP]->frame_parms;
- NR_MIB_t *mib = RC.nrrrc[module_idP]->carrier.mib.message.choice.mib;
- uint8_t gNB_xtra_byte = 0;
- for (int i = 0; i < 8; i++) {
- gNB_xtra_byte |= ((RC.gNB[module_idP]->pbch.pbch_a >> (31 - i)) & 1) << (7 - i);
- }
- get_type0_PDCCH_CSS_config_parameters(&gNB->type0_PDCCH_CSS_config, mib, gNB_xtra_byte, frame_parms->Lmax,
- frame_parms->ssb_index, frame_parms->ssb_start_subcarrier/NR_NB_SC_PER_RB);
+ mib_sdu_length = mac_rrc_nr_data_req(module_idP, CC_id, frameP, MIBCH, 1, &cc->MIB_pdu.payload[0]);
+ LOG_D(MAC,
+ "[gNB %d] Frame %d : MIB->BCH CC_id %d, Received %d bytes\n",
+ module_idP,
+ frameP,
+ CC_id,
+ mib_sdu_length);
}
- // checking if there is any SSB in slot
- const int abs_slot = (slots_per_frame * frameP) + slotP;
- const int slot_per_period = (slots_per_frame>>1)<<(*scc->ssb_periodicityServingCell);
- int eff_120_slot;
- const BIT_STRING_t *shortBitmap = &scc->ssb_PositionsInBurst->choice.shortBitmap;
- const BIT_STRING_t *mediumBitmap = &scc->ssb_PositionsInBurst->choice.mediumBitmap;
- const BIT_STRING_t *longBitmap = &scc->ssb_PositionsInBurst->choice.longBitmap;
- uint8_t buf = 0;
- switch (scc->ssb_PositionsInBurst->present) {
- case 1:
- // presence of ssbs possible in the first 2 slots of ssb period
- if ((abs_slot % slot_per_period) < 2 &&
- (((shortBitmap->buf[0]) >> (6 - (slotP << 1))) & 3) != 0)
- fill_ssb_vrb_map(cc, (ssb_offset0 / (ratio * 12) - 10), CC_id);
- break;
- case 2:
- // presence of ssbs possible in the first 4 slots of ssb period
- if ((abs_slot % slot_per_period) < 4 &&
- (((mediumBitmap->buf[0]) >> (6 - (slotP << 1))) & 3) != 0)
- fill_ssb_vrb_map(cc, (ssb_offset0 / (ratio * 12) - 10), CC_id);
- break;
- case 3:
- AssertFatal(*scc->ssbSubcarrierSpacing ==
- NR_SubcarrierSpacing_kHz120,
- "240kHZ subcarrier spacing currently not supported for SSBs\n");
- if ((abs_slot % slot_per_period) < 8) {
- eff_120_slot = slotP;
- if((abs_slot % slot_per_period) < 3)
- buf = longBitmap->buf[0];
- else
- buf = longBitmap->buf[1];
- } else if ((abs_slot % slot_per_period) < 18) {
- eff_120_slot = slotP - 10;
- if((abs_slot % slot_per_period) < 13)
- buf = longBitmap->buf[2];
- else
- buf = longBitmap->buf[3];
- } else if ((abs_slot % slot_per_period) < 28) {
- eff_120_slot = slotP - 20;
- if((abs_slot % slot_per_period) < 23)
- buf = longBitmap->buf[4];
- else
- buf = longBitmap->buf[5];
- } else if ((abs_slot % slot_per_period) < 38) {
- eff_120_slot = slotP - 30;
- if((abs_slot % slot_per_period) < 33)
- buf = longBitmap->buf[6];
- else
- buf = longBitmap->buf[7];
- }
- if ((eff_120_slot>=0) && (((buf >> (6 - (eff_120_slot << 1))) & 3) != 0)) {
- AssertFatal(((buf >> (6 - (eff_120_slot << 1))) & 3)<3,"We only support 1 ssb per slot max in FR2 for the moment\n");
- fill_ssb_vrb_map(cc, ssb_offset0 / (ratio * 12) - 10, CC_id);
- }
- break;
- default:
- AssertFatal(0,"SSB bitmap size value %d undefined (allowed values 1,2,3)\n",
- scc->ssb_PositionsInBurst->present);
- }
- // For FR2 beam ssb association at the beginning of every SSB period
- if((scc->ssb_PositionsInBurst->present==3) && (abs_slot%slot_per_period == 0)){
- uint8_t i_ssb,num_tdd_period;
- uint8_t num_ssb = 0;
- for (int i=0; i<64; i++){
- i_ssb=((longBitmap->buf[i/8])>>(7-(i%8)))&1;
- if(i_ssb==1){
- num_tdd_period = SSB_Slot[i]/(slots_per_frame/nb_periods_per_frame);
- gNB->tdd_beam_association[num_tdd_period]=num_ssb;
- num_ssb++;
- }
+ int8_t ssb_period = *scc->ssb_periodicityServingCell;
+ uint8_t ssb_frame_periodicity = 1; // every how many frames SSB are generated
+
+ if (ssb_period > 1) // 0 is every half frame
+ ssb_frame_periodicity = 1 << (ssb_period -1);
+
+ if (!(frameP%ssb_frame_periodicity) &&
+ ((slotP<(slots_per_frame>>1)) || (ssb_period == 0))) {
+ // schedule SSB only for given frames according to SSB periodicity
+ // and in first half frame unless periodicity of 5ms
+ int rel_slot;
+ if (ssb_period == 0) // scheduling every half frame
+ rel_slot = slotP%(slots_per_frame>>1);
+ else
+ rel_slot = slotP;
+
+ NR_SubcarrierSpacing_t scs = *scc->ssbSubcarrierSpacing;
+ const long band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
+ uint16_t offset_pointa = get_ssboffset_pointa(scc,band);
+ uint8_t ssbSubcarrierOffset = gNB->ssb_SubcarrierOffset;
+
+ const BIT_STRING_t *shortBitmap = &scc->ssb_PositionsInBurst->choice.shortBitmap;
+ const BIT_STRING_t *mediumBitmap = &scc->ssb_PositionsInBurst->choice.mediumBitmap;
+ const BIT_STRING_t *longBitmap = &scc->ssb_PositionsInBurst->choice.longBitmap;
+
+ uint16_t ssb_start_symbol;
+
+ switch (scc->ssb_PositionsInBurst->present) {
+ case 1:
+ // short bitmap (<3GHz) max 4 SSBs
+ for (int i_ssb=0; i_ssb<4; i_ssb++) {
+ if ((shortBitmap->buf[0]>>(7-i_ssb))&0x01) {
+ ssb_start_symbol = get_ssb_start_symbol(band,scs,i_ssb);
+ // if start symbol is in current slot, schedule current SSB, fill VRB map and call get_type0_PDCCH_CSS_config_parameters
+ if ((ssb_start_symbol/14) == rel_slot){
+ schedule_ssb(frameP, slotP, scc, dl_req, i_ssb, ssbSubcarrierOffset, offset_pointa, (*(uint32_t*)cc->MIB_pdu.payload) & ((1<<24)-1));
+ fill_ssb_vrb_map(cc, offset_pointa, ssb_start_symbol, CC_id);
+ if (get_softmodem_params()->sa == 1) {
+ get_type0_PDCCH_CSS_config_parameters(&gNB->type0_PDCCH_CSS_config[i_ssb],
+ frameP,
+ mib,
+ slots_per_frame,
+ ssbSubcarrierOffset,
+ ssb_start_symbol,
+ scs,
+ FR1,
+ i_ssb,
+ offset_pointa);
+ gNB->type0_PDCCH_CSS_config[i_ssb].active = true;
+ }
+ }
+ }
+ }
+ break;
+ case 2:
+ // medium bitmap (<6GHz) max 8 SSBs
+ for (int i_ssb=0; i_ssb<8; i_ssb++) {
+ if ((mediumBitmap->buf[0]>>(7-i_ssb))&0x01) {
+ ssb_start_symbol = get_ssb_start_symbol(band,scs,i_ssb);
+ // if start symbol is in current slot, schedule current SSB, fill VRB map and call get_type0_PDCCH_CSS_config_parameters
+ if ((ssb_start_symbol/14) == rel_slot){
+ schedule_ssb(frameP, slotP, scc, dl_req, i_ssb, ssbSubcarrierOffset, offset_pointa, (*(uint32_t*)cc->MIB_pdu.payload) & ((1<<24)-1));
+ fill_ssb_vrb_map(cc, offset_pointa, ssb_start_symbol, CC_id);
+ if (get_softmodem_params()->sa == 1) {
+ get_type0_PDCCH_CSS_config_parameters(&gNB->type0_PDCCH_CSS_config[i_ssb],
+ frameP,
+ mib,
+ slots_per_frame,
+ ssbSubcarrierOffset,
+ ssb_start_symbol,
+ scs,
+ FR1,
+ i_ssb,
+ offset_pointa);
+ gNB->type0_PDCCH_CSS_config[i_ssb].active = true;
+ }
+ }
+ }
+ }
+ break;
+ case 3:
+ // long bitmap FR2 max 64 SSBs
+ num_ssb = 0;
+ for (int i_ssb=0; i_ssb<63; i_ssb++) {
+ if ((longBitmap->buf[i_ssb/8]>>(7-i_ssb))&0x01) {
+ ssb_start_symbol = get_ssb_start_symbol(band,scs,i_ssb);
+ // if start symbol is in current slot, schedule current SSB, fill VRB map and call get_type0_PDCCH_CSS_config_parameters
+ if ((ssb_start_symbol/14) == rel_slot){
+ schedule_ssb(frameP, slotP, scc, dl_req, i_ssb, ssbSubcarrierOffset, offset_pointa, (*(uint32_t*)cc->MIB_pdu.payload) & ((1<<24)-1));
+ fill_ssb_vrb_map(cc, offset_pointa, ssb_start_symbol, CC_id);
+ num_tdd_period = rel_slot/(slots_per_frame/nb_periods_per_frame);
+ gNB->tdd_beam_association[num_tdd_period]=i_ssb;
+ num_ssb++;
+ AssertFatal(num_ssb<2,"beamforming currently not supported for more than one SSB per slot\n");
+ if (get_softmodem_params()->sa == 1) {
+ get_type0_PDCCH_CSS_config_parameters(&gNB->type0_PDCCH_CSS_config[i_ssb],
+ frameP,
+ mib,
+ slots_per_frame,
+ ssbSubcarrierOffset,
+ ssb_start_symbol,
+ scs,
+ FR2,
+ i_ssb,
+ offset_pointa);
+ gNB->type0_PDCCH_CSS_config[i_ssb].active = true;
+ }
+ }
+ }
+ }
+ break;
+ default:
+ AssertFatal(0,"SSB bitmap size value %d undefined (allowed values 1,2,3)\n",
+ scc->ssb_PositionsInBurst->present);
}
}
}
@@ -265,14 +293,22 @@ void schedule_nr_SI(module_id_t module_idP, frame_t frameP, sub_frame_t subframe
//----------------------------------------
}
-void fill_ssb_vrb_map (NR_COMMON_channels_t *cc, int rbStart, int CC_id) {
+void fill_ssb_vrb_map (NR_COMMON_channels_t *cc, int rbStart, uint16_t symStart, int CC_id) {
+
+ AssertFatal(*cc->ServingCellConfigCommon->ssbSubcarrierSpacing !=
+ NR_SubcarrierSpacing_kHz240,
+ "240kHZ subcarrier won't work with current VRB map because a single SSB might be across 2 slots\n");
+
uint16_t *vrb_map = cc[CC_id].vrb_map;
+
for (int rb = 0; rb < 20; rb++)
- vrb_map[rbStart + rb] = 1;
+ vrb_map[rbStart + rb] = 15<sched_ctrlCommon->cce_index >= 0, "Could not find CCE for coreset0\n");
- const uint16_t bwpSize = gNB_mac->type0_PDCCH_CSS_config.num_rbs;
- int rbStart = gNB_mac->type0_PDCCH_CSS_config.cset_start_rb;
+ const uint16_t bwpSize = type0_PDCCH_CSS_config->num_rbs;
+ int rbStart = type0_PDCCH_CSS_config->cset_start_rb;
int startSymbolIndex = 0;
int nrOfSymbols = 0;
@@ -361,6 +397,7 @@ void schedule_control_sib1(module_id_t module_id,
void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP,
nfapi_nr_dl_tti_request_body_t *dl_req,
+ NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config,
uint32_t TBS,
int StartSymbolIndex,
int NrOfSymbols) {
@@ -384,8 +421,8 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP,
bwp);
// TODO: This assignment should be done in function nr_configure_pdcch()
- pdcch_pdu_rel15->BWPSize = gNB_mac->type0_PDCCH_CSS_config.num_rbs;
- pdcch_pdu_rel15->BWPStart = gNB_mac->type0_PDCCH_CSS_config.cset_start_rb;
+ pdcch_pdu_rel15->BWPSize = gNB_mac->type0_PDCCH_CSS_config->num_rbs;
+ pdcch_pdu_rel15->BWPStart = gNB_mac->type0_PDCCH_CSS_config->cset_start_rb;
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
memset((void*)dl_tti_pdsch_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t));
@@ -400,8 +437,8 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP,
pdsch_pdu_rel15->rnti = SI_RNTI;
pdsch_pdu_rel15->pduIndex = gNB_mac->pdu_index[0]++;
- pdsch_pdu_rel15->BWPSize = gNB_mac->type0_PDCCH_CSS_config.num_rbs;
- pdsch_pdu_rel15->BWPStart = gNB_mac->type0_PDCCH_CSS_config.cset_start_rb;
+ pdsch_pdu_rel15->BWPSize = type0_PDCCH_CSS_config->num_rbs;
+ pdsch_pdu_rel15->BWPStart = type0_PDCCH_CSS_config->cset_start_rb;
pdsch_pdu_rel15->SubcarrierSpacing = bwp->bwp_Common->genericParameters.subcarrierSpacing;
if (bwp->bwp_Common->genericParameters.cyclicPrefix) {
@@ -458,7 +495,7 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP,
// frequency domain assignment
dci_payload.frequency_domain_assignment.val = PRBalloc_to_locationandbandwidth0(
- pdsch_pdu_rel15->rbSize, pdsch_pdu_rel15->rbStart, gNB_mac->type0_PDCCH_CSS_config.num_rbs);
+ pdsch_pdu_rel15->rbSize, pdsch_pdu_rel15->rbStart, type0_PDCCH_CSS_config->num_rbs);
dci_payload.time_domain_assignment.val = gNB_mac->sched_ctrlCommon->time_domain_allocation;
dci_payload.mcs = gNB_mac->sched_ctrlCommon->mcs;
@@ -513,20 +550,44 @@ void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
uint8_t candidate_idx = 0;
gNB_MAC_INST *gNB_mac = RC.nrmac[module_idP];
+ NR_ServingCellConfigCommon_t *scc = gNB_mac->common_channels[CC_id].ServingCellConfigCommon;
- if( (frameP%2 == gNB_mac->type0_PDCCH_CSS_config.sfn_c) && (slotP == gNB_mac->type0_PDCCH_CSS_config.n_0) && (gNB_mac->type0_PDCCH_CSS_config.num_rbs > 0) ) {
+ int L_max;
+ switch (scc->ssb_PositionsInBurst->present) {
+ case 1:
+ L_max = 4;
+ break;
+ case 2:
+ L_max = 8;
+ break;
+ case 3:
+ L_max = 64;
+ break;
+ default:
+ AssertFatal(0,"SSB bitmap size value %d undefined (allowed values 1,2,3)\n",
+ scc->ssb_PositionsInBurst->present);
+ }
- LOG_D(MAC,"> SIB1 transmission\n");
+ for (int i=0; itype0_PDCCH_CSS_config[i];
- // Configure sched_ctrlCommon for SIB1
- schedule_control_sib1(module_idP, CC_id, time_domain_allocation, mcsTableIdx, mcs, candidate_idx, sib1_sdu_length);
+ if((frameP%2 == type0_PDCCH_CSS_config->sfn_c) &&
+ (slotP == type0_PDCCH_CSS_config->n_0) &&
+ (type0_PDCCH_CSS_config->num_rbs > 0) &&
+ (type0_PDCCH_CSS_config->active == true)) {
+
+ LOG_D(MAC,"> SIB1 transmission\n");
+
+ // Get SIB1
+ uint8_t sib1_payload[NR_MAX_SIB_LENGTH/8];
+ uint8_t sib1_sdu_length = mac_rrc_nr_data_req(module_idP, CC_id, frameP, BCCH, 1, sib1_payload);
+ LOG_D(MAC,"sib1_sdu_length = %i\n", sib1_sdu_length);
+ LOG_D(MAC,"SIB1: \n");
+ for (int i=0;icommon_channels->ServingCellConfigCommon->dmrs_TypeA_Position, nrOfSymbols, startSymbolIndex);
uint16_t dmrs_length = get_num_dmrs(dlDmrsSymbPos);
- const uint32_t TBS = nr_compute_tbs(nr_get_Qm_dl(gNB_mac->sched_ctrlCommon->mcs, gNB_mac->sched_ctrlCommon->mcsTableIdx),
- nr_get_code_rate_dl(gNB_mac->sched_ctrlCommon->mcs, gNB_mac->sched_ctrlCommon->mcsTableIdx),
- gNB_mac->sched_ctrlCommon->rbSize, nrOfSymbols, N_PRB_DMRS * dmrs_length,0 ,0 ,1 ) >> 3;
+ const uint32_t TBS = nr_compute_tbs(nr_get_Qm_dl(gNB_mac->sched_ctrlCommon->mcs, gNB_mac->sched_ctrlCommon->mcsTableIdx),
+ nr_get_code_rate_dl(gNB_mac->sched_ctrlCommon->mcs, gNB_mac->sched_ctrlCommon->mcsTableIdx),
+ gNB_mac->sched_ctrlCommon->rbSize, nrOfSymbols, N_PRB_DMRS * dmrs_length,0 ,0 ,1 ) >> 3;
- nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[CC_id].dl_tti_request_body;
- nr_fill_nfapi_dl_sib1_pdu(module_idP, dl_req, TBS, startSymbolIndex, nrOfSymbols);
+ nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[CC_id].dl_tti_request_body;
+ nr_fill_nfapi_dl_sib1_pdu(module_idP, dl_req, type0_PDCCH_CSS_config, TBS, startSymbolIndex, nrOfSymbols);
- const int ntx_req = gNB_mac->TX_req[CC_id].Number_of_PDUs;
- nfapi_nr_pdu_t *tx_req = &gNB_mac->TX_req[CC_id].pdu_list[ntx_req];
+ const int ntx_req = gNB_mac->TX_req[CC_id].Number_of_PDUs;
+ nfapi_nr_pdu_t *tx_req = &gNB_mac->TX_req[CC_id].pdu_list[ntx_req];
- // Data to be transmitted
- bzero(tx_req->TLVs[0].value.direct,MAX_NR_DLSCH_PAYLOAD_BYTES);
- memcpy(tx_req->TLVs[0].value.direct, sib1_payload, sib1_sdu_length);
+ // Data to be transmitted
+ bzero(tx_req->TLVs[0].value.direct,MAX_NR_DLSCH_PAYLOAD_BYTES);
+ memcpy(tx_req->TLVs[0].value.direct, sib1_payload, sib1_sdu_length);
- tx_req->PDU_length = TBS;
- tx_req->PDU_index = gNB_mac->pdu_index[0]++;
- tx_req->num_TLV = 1;
- tx_req->TLVs[0].length = TBS + 2;
- gNB_mac->TX_req[CC_id].Number_of_PDUs++;
- gNB_mac->TX_req[CC_id].SFN = frameP;
- gNB_mac->TX_req[CC_id].Slot = slotP;
+ tx_req->PDU_length = TBS;
+ tx_req->PDU_index = gNB_mac->pdu_index[0]++;
+ tx_req->num_TLV = 1;
+ tx_req->TLVs[0].length = TBS + 2;
+ gNB_mac->TX_req[CC_id].Number_of_PDUs++;
+ gNB_mac->TX_req[CC_id].SFN = frameP;
+ gNB_mac->TX_req[CC_id].Slot = slotP;
+
+ type0_PDCCH_CSS_config->active = false;
+ }
}
}
diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
index 42f3bbf70f..05c180ca2e 100644
--- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
+++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
@@ -41,6 +41,7 @@ void set_cset_offset(uint16_t);
void mac_top_init_gNB(void);
void config_common(int Mod_idP,
+ int ssb_SubcarrierOffset,
int pdsch_AntennaPorts,
int pusch_AntennaPorts,
NR_ServingCellConfigCommon_t *scc
@@ -72,6 +73,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
void schedule_control_sib1(module_id_t module_id,
int CC_id,
+ NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config,
int time_domain_allocation,
uint8_t mcsTableIdx,
uint8_t mcs,
@@ -379,7 +381,7 @@ int binomial(int n, int k);
bool is_xlsch_in_slot(uint64_t bitmap, sub_frame_t slot);
-void fill_ssb_vrb_map (NR_COMMON_channels_t *cc, int rbStart, int CC_id);
+void fill_ssb_vrb_map (NR_COMMON_channels_t *cc, int rbStart, uint16_t symStart, int CC_id);
/* \brief Function to indicate a received SDU on ULSCH.
diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
index 8452ca3c4c..d9869e7a7b 100644
--- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
+++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
@@ -611,6 +611,8 @@ typedef struct gNB_MAC_INST_s {
int pusch_target_snrx10;
/// Pucch target SNR
int pucch_target_snrx10;
+ /// Subcarrier Offset
+ int ssb_SubcarrierOffset;
/// Common cell resources
NR_COMMON_channels_t common_channels[NFAPI_CC_MAX];
/// current PDU index (BCH,DLSCH)
@@ -677,7 +679,7 @@ typedef struct gNB_MAC_INST_s {
NR_UE_sched_ctrl_t *sched_ctrlCommon;
NR_CellGroupConfig_t *secondaryCellGroupCommon;
- NR_Type0_PDCCH_CSS_config_t type0_PDCCH_CSS_config;
+ NR_Type0_PDCCH_CSS_config_t type0_PDCCH_CSS_config[64];
} gNB_MAC_INST;
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpn300.conf
index 39ee3c4a61..477240a3a0 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpn300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpn300.conf
@@ -23,6 +23,7 @@ gNBs =
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1;
+ pusch_AntennaPorts = 1;
pusch_TargetSNRx10 = 200;
pucch_TargetSNRx10 = 200;