Commit dd2cefa4 authored by Raymond Knopp's avatar Raymond Knopp

added longer prefix in PRACH symbol zero period for 15/30 kHz SCS. Both gNB...

added longer prefix in PRACH symbol zero period for 15/30 kHz SCS. Both gNB and UE processing is modified. prachsim is functional again with new FAPI interfaces.
parent 46c2c119
......@@ -1578,7 +1578,11 @@ void *ru_thread( void *param ) {
// Do PRACH RU processing
int prach_id=find_nr_prach_ru(ru,proc->frame_rx,proc->tti_rx,SEARCH_EXIST);
if (prach_id>=0) {
rx_nr_prach_ru(ru,ru->prach_list[prach_id].fmt,proc->frame_rx,proc->tti_rx);
rx_nr_prach_ru(ru,
ru->prach_list[prach_id].fmt,
ru->prach_list[prach_id].numRA,
ru->prach_list[prach_id].prachStartSymbol,
proc->frame_rx,proc->tti_rx);
free_nr_ru_prach_entry(ru,prach_id);
}
}
......
......@@ -387,7 +387,7 @@ void nr_phy_config_request_sim(PHY_VARS_gNB *gNB,
fp->dl_CarrierFreq = 3500000000;//from_nrarfcn(gNB_config->nfapi_config.rf_bands.rf_band[0],gNB_config->nfapi_config.nrarfcn.value);
fp->ul_CarrierFreq = 3500000000;//fp->dl_CarrierFreq - (get_uldl_offset(gNB_config->nfapi_config.rf_bands.rf_band[0])*100000);
fp->nr_band = 78;
fp->threequarter_fs= 0;
// fp->threequarter_fs= 0;
gNB_config->carrier_config.dl_bandwidth.value = config_bandwidth(mu, N_RB_DL, fp->nr_band);
......
......@@ -120,9 +120,11 @@ void nr_fill_prach_ru(RU_t *ru,
"illegal or no prach_id found!!! prach_id %d\n",prach_id);
pthread_mutex_lock(&ru->prach_list_mutex);
ru->prach_list[prach_id].frame = SFN;
ru->prach_list[prach_id].slot = Slot;
ru->prach_list[prach_id].fmt = prach_pdu->prach_format;
ru->prach_list[prach_id].frame = SFN;
ru->prach_list[prach_id].slot = Slot;
ru->prach_list[prach_id].fmt = prach_pdu->prach_format;
ru->prach_list[prach_id].numRA = prach_pdu->num_ra;
ru->prach_list[prach_id].prachStartSymbol = prach_pdu->prach_start_symbol;
pthread_mutex_unlock(&ru->prach_list_mutex);
}
......@@ -139,7 +141,9 @@ void free_nr_ru_prach_entry(RU_t *ru,
const char *prachfmt[]={"A1","A2","A3","B1","B2","B3","B4","C0","C2"};
void rx_nr_prach_ru(RU_t *ru,
int prach_fmt,
int prachFormat,
int numRA,
int prachStartSymbol,
int frame,
int slot) {
......@@ -151,7 +155,7 @@ void rx_nr_prach_ru(RU_t *ru,
int16_t *prach[ru->nb_rx];
int prach_sequence_length = ru->config.prach_config.prach_sequence_length.value;
int msg1_frequencystart = ru->config.prach_config.num_prach_fd_occasions_list[0].k1.value;
int msg1_frequencystart = ru->config.prach_config.num_prach_fd_occasions_list[numRA].k1.value;
rxsigF = ru->prach_rxsigF;
......@@ -167,9 +171,9 @@ void rx_nr_prach_ru(RU_t *ru,
if (prach_sequence_length == 0) {
LOG_D(PHY,"PRACH (ru %d) in %d.%d, format %d, msg1_frequencyStart %d\n",
ru->idx,frame,slot,prach_fmt,msg1_frequencystart);
AssertFatal(prach_fmt<4,"Illegal prach format %d for length 839\n",prach_fmt);
switch (prach_fmt) {
ru->idx,frame,slot,prachFormat,msg1_frequencystart);
AssertFatal(prachFormat<4,"Illegal prach format %d for length 839\n",prachFormat);
switch (prachFormat) {
case 0:
Ncp = 3168;
break;
......@@ -189,11 +193,11 @@ void rx_nr_prach_ru(RU_t *ru,
}
}
else {
LOG_D(PHY,"PRACH (ru %d) in %d.%d, format %s, msg1_frequencyStart %d\n",
ru->idx,frame,slot,prachfmt[prach_fmt],msg1_frequencystart);
LOG_D(PHY,"PRACH (ru %d) in %d.%d, format %s, msg1_frequencyStart %d,startSymbol %d\n",
ru->idx,frame,slot,prachfmt[prachFormat],msg1_frequencystart,prachStartSymbol);
switch (prach_fmt) {
AssertFatal(prach_fmt<4,"Illegal prach format %d for length 139 (combined formats not supported yet)\n",prach_fmt);
switch (prachFormat) {
AssertFatal(prachFormat<4,"Illegal prach format %d for length 139 (combined formats not supported yet)\n",prachFormat);
case 0: //A1
Ncp = 288/(1<<mu);
break;
......@@ -231,7 +235,7 @@ void rx_nr_prach_ru(RU_t *ru,
break;
default:
AssertFatal(1==0,"unknown prach format %x\n",prach_fmt);
AssertFatal(1==0,"unknown prach format %x\n",prachFormat);
break;
}
}
......@@ -244,7 +248,7 @@ void rx_nr_prach_ru(RU_t *ru,
// Note: Assumes PUSCH SCS @ 30 kHz, take values for formats 0-2 and adjust for others below
int kbar = 1;
int K = 24;
if (prach_sequence_length == 0 && prach_fmt == 3) {
if (prach_sequence_length == 0 && prachFormat == 3) {
K=4;
kbar=10;
}
......@@ -276,95 +280,114 @@ void rx_nr_prach_ru(RU_t *ru,
if (fp->threequarter_fs==0) {
//40 MHz @ 61.44 Ms/s
//50 MHz @ 61.44 Ms/s
prach2 = prach[aa] + (Ncp<<2);
prach2 = prach[aa] + (Ncp<<2); // Ncp is for 30.72 Ms/s, so multiply by 2 for I/Q, and 2 to bring to 61.44 Ms/s
if (prach_sequence_length == 0) {
if (prach_fmt == 0 || prach_fmt == 1 || prach_fmt == 2) {
if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) {
dftlen=49152;
dft49152(prach2,rxsigF[aa],1);
}
if (prach_fmt == 1 || prach_fmt == 2) {
if (prachFormat == 1 || prachFormat == 2) {
dft49152(prach2+98304,rxsigF[aa]+98304,1);
reps++;
}
if (prach_fmt == 2) {
if (prachFormat == 2) {
dft49152(prach2+(98304*2),rxsigF[aa]+(98304*2),1);
dft49152(prach2+(98304*3),rxsigF[aa]+(98304*3),1);
reps+=2;
}
if (prach_fmt == 3) {
if (prachFormat == 3) {
dftlen=12288;
for (int i=0;i<4;i++) dft12288(prach2+(i*12288*2),rxsigF[aa]+(i*12288*2),1);
reps=4;
}
}
}// 839 sequence
else {
dftlen=2048;
dft2048(prach2,rxsigF[aa],1);
if (prach_fmt != 7) { // !=C0
dft2048(prach2+4096,rxsigF[aa]+4096,1);
reps++;
}
if (prach_fmt == 1 || prach_fmt == 2 || prach_fmt == 4 || prach_fmt == 5 || prach_fmt == 6 || prach_fmt == 8) {
dft2048(prach2+4096*2,rxsigF[aa]+4096*2,1);
dft2048(prach2+4096*3,rxsigF[aa]+4096*3,1);
reps+=2;
}
if (prach_fmt == 2 || prach_fmt == 5 || prach_fmt == 6) {
dft2048(prach2+4096*4,rxsigF[aa]+4096*4,1);
dft2048(prach2+4096*5,rxsigF[aa]+4096*5,1);
reps+=2;
}
if (prach_fmt == 6) {
for (int i=6;i<12;i++) dft2048(prach2+(4096*i),rxsigF[aa]+(4096*i),1);
reps+=6;
if ((mu==0 &&
(prachStartSymbol == 0 || prachStartSymbol == 7)) ||
(mu==1 && prachStartSymbol == 0)) prach2+=64; // 32 samples @ 61.44 Ms/s in first symbol of each half subframe (15/30 kHz only)
if (mu==0) AssertFatal(1==0,"Shouldn't get here\n");
else if (mu==1) {
dftlen=2048;
dft2048(prach2,rxsigF[aa],1);
if (prachFormat != 7) { // !=C0
dft2048(prach2+4096,rxsigF[aa]+4096,1);
reps++;
}
if (prachFormat == 1 || prachFormat == 2 || prachFormat == 4 || prachFormat == 5 || prachFormat == 6 || prachFormat == 8) {
dft2048(prach2+4096*2,rxsigF[aa]+4096*2,1);
dft2048(prach2+4096*3,rxsigF[aa]+4096*3,1);
reps+=2;
}
if (prachFormat == 2 || prachFormat == 5 || prachFormat == 6) {
dft2048(prach2+4096*4,rxsigF[aa]+4096*4,1);
dft2048(prach2+4096*5,rxsigF[aa]+4096*5,1);
reps+=2;
}
if (prachFormat == 6) {
for (int i=6;i<12;i++) dft2048(prach2+(4096*i),rxsigF[aa]+(4096*i),1);
reps+=6;
}
}
else if (mu==2) AssertFatal(1==0,"Shouldn't get here\n");
else if (mu==3) AssertFatal(1==0,"Shouldn't get here\n");
else if (mu==4) AssertFatal(1==0,"Shouldn't get here\n");
}
} else {
} else { // threequarter sampling
// 40 MHz @ 46.08 Ms/s
prach2 = prach[aa] + (3*Ncp);
prach2 = prach[aa] + (3*Ncp); // 46.08 is 1.5 * 30.72, times 2 for I/Q
if (prach_sequence_length == 0) {
AssertFatal(fp->N_RB_UL <= 107,"cannot do 108..136 PRBs with 3/4 sampling\n");
if (prach_fmt == 0 || prach_fmt == 1 || prach_fmt == 2) {
dftlen=36864;
if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) {
dftlen=36864;
dft36864(prach2,rxsigF[aa],1);
reps++;
}
if (prach_fmt == 1 || prach_fmt == 2) {
if (prachFormat == 1 || prachFormat == 2) {
dft36864(prach2+73728,rxsigF[aa]+73728,1);
reps++;
}
if (prach_fmt == 2) {
if (prachFormat == 2) {
dft36864(prach2+(73728*2),rxsigF[aa]+(73728*2),1);
dft36864(prach2+(73728*3),rxsigF[aa]+(73728*3),1);
reps+=2;
}
if (prach_fmt == 3) {
dftlen=9216;
if (prachFormat == 3) {
dftlen=9216;
for (int i=0;i<4;i++) dft9216(prach2+(i*9216*2),rxsigF[aa]+(i*9216*2),1);
reps=4;
}
} else {
dftlen=1536;
dft1536(prach2,rxsigF[aa],1);
if (prach_fmt != 7) {
dft1536(prach2+3072,rxsigF[aa]+3072,1);
reps++;
}
if (prach_fmt == 1 || prach_fmt == 2 || prach_fmt == 4 || prach_fmt == 5 || prach_fmt == 6 || prach_fmt == 8) {
dft1536(prach2+3072*2,rxsigF[aa]+3072*2,1);
dft1536(prach2+3072*3,rxsigF[aa]+3072*3,1);
reps+=2;
}
if (prach_fmt == 2 || prach_fmt == 5 || prach_fmt == 6) {
dft1536(prach2+3072*4,rxsigF[aa]+3072*4,1);
dft1536(prach2+3072*5,rxsigF[aa]+3072*5,1);
reps+=2;
}
if (prach_fmt == 6) {
for (int i=6;i<12;i++) dft1536(prach2+(3072*i),rxsigF[aa]+(3072*i),1);
reps+=6;
}
if ((mu==0 &&
(prachStartSymbol == 0 || prachStartSymbol == 7)) ||
(mu==1 && prachStartSymbol == 0)) prach2+=48; // 24 samples @ 43.08 Ms/s in first symbol of each half subframe (15/30 kHz only)
if (mu==0) AssertFatal(1==0,"Shouldn't get here\n");
else if (mu==1) {
dftlen=1536;
dft1536(prach2,rxsigF[aa],1);
if (prachFormat != 7) {
dft1536(prach2+3072,rxsigF[aa]+3072,1);
reps++;
}
if (prachFormat == 1 || prachFormat == 2 || prachFormat == 4 || prachFormat == 5 || prachFormat == 6 || prachFormat == 8) {
dft1536(prach2+3072*2,rxsigF[aa]+3072*2,1);
dft1536(prach2+3072*3,rxsigF[aa]+3072*3,1);
reps+=2;
}
if (prachFormat == 2 || prachFormat == 5 || prachFormat == 6) {
dft1536(prach2+3072*4,rxsigF[aa]+3072*4,1);
dft1536(prach2+3072*5,rxsigF[aa]+3072*5,1);
reps+=2;
}
if (prachFormat == 6) {
for (int i=6;i<12;i++) dft1536(prach2+(3072*i),rxsigF[aa]+(3072*i),1);
reps+=6;
}
}// mu==1
else if (mu==2) AssertFatal(1==0,"Shouldn't get here\n");
else if (mu==3) AssertFatal(1==0,"Shouldn't get here\n");
else if (mu==4) AssertFatal(1==0,"Shouldn't get here\n");
} // short format
} // 3/4 sampling
} // <=50 MHz BW
......@@ -374,89 +397,109 @@ void rx_nr_prach_ru(RU_t *ru,
//80,90,100 MHz @ 122.88 Ms/s
if (prach_sequence_length == 0) {
if (prach_fmt == 0 || prach_fmt == 1 || prach_fmt == 2) {
if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) {
dftlen=98304;
dft98304(prach2,rxsigF[aa],1);
}
if (prach_fmt == 1 || prach_fmt == 2) {
if (prachFormat == 1 || prachFormat == 2) {
dft98304(prach2+196608,rxsigF[aa]+196608,1);
reps++;
}
if (prach_fmt == 2) {
if (prachFormat == 2) {
dft98304(prach2+196608*2,rxsigF[aa]+196608*2,1);
dft98304(prach2+(196608*3),rxsigF[aa]+(196608*3),1);
reps+=2;
}
if (prach_fmt == 3) {
if (prachFormat == 3) {
dftlen=24576;
for (int i=0;i<4;i++) dft24576(prach2+(i*2*24576),rxsigF[aa]+(i*2*24576),1);
reps=4;
}
}
else {
dftlen=4096;
dft4096(prach2,rxsigF[aa],1);
if (prach_fmt != 7) { //!=C0
dft4096(prach2+8192,rxsigF[aa]+8192,1);
reps++;
}
if (prach_fmt == 1 || prach_fmt == 2 || prach_fmt == 4 || prach_fmt == 5 || prach_fmt == 6 || prach_fmt == 8) {
dft4096(prach2+8192*2,rxsigF[aa]+8192*2,1);
dft4096(prach2+8192*3,rxsigF[aa]+8192*3,1);
reps+=2;
}
if (prach_fmt == 2 || prach_fmt == 5 || prach_fmt == 6) {
dft4096(prach2+8192*4,rxsigF[aa]+8192*4,1);
dft4096(prach2+8192*5,rxsigF[aa]+8192*5,1);
reps+=2;
}
if (prach_fmt == 6) {
for (int i=6;i<12;i++) dft4096(prach2+(8192*i),rxsigF[aa]+(8192*i),1);
reps+=6;
if ((mu==0 &&
(prachStartSymbol == 0 || prachStartSymbol == 7)) ||
(mu==1 && prachStartSymbol == 0)) prach2+=128; // 64 samples @ 122.88 Ms/s in first symbol of each half subframe (15/30 kHz only)
if (mu==0) AssertFatal(1==0,"Shouldn't get here\n");
else if (mu==1) {
dftlen=4096;
dft4096(prach2,rxsigF[aa],1);
if (prachFormat != 7) { //!=C0
dft4096(prach2+8192,rxsigF[aa]+8192,1);
reps++;
}
if (prachFormat == 1 || prachFormat == 2 || prachFormat == 4 || prachFormat == 5 || prachFormat == 6 || prachFormat == 8) {
dft4096(prach2+8192*2,rxsigF[aa]+8192*2,1);
dft4096(prach2+8192*3,rxsigF[aa]+8192*3,1);
reps+=2;
}
if (prachFormat == 2 || prachFormat == 5 || prachFormat == 6) {
dft4096(prach2+8192*4,rxsigF[aa]+8192*4,1);
dft4096(prach2+8192*5,rxsigF[aa]+8192*5,1);
reps+=2;
}
if (prachFormat == 6) {
for (int i=6;i<12;i++) dft4096(prach2+(8192*i),rxsigF[aa]+(8192*i),1);
reps+=6;
}
}
else if (mu==2) AssertFatal(1==0,"Shouldn't get here\n");
else if (mu==3) AssertFatal(1==0,"Shouldn't get here\n");
else if (mu==4) AssertFatal(1==0,"Shouldn't get here\n");
}
} else {
AssertFatal(fp->N_RB_UL <= 217,"cannot do more than 217 PRBs with 3/4 sampling\n");
prach2 = prach[aa] + (6*Ncp);
// 80 MHz @ 92.16 Ms/s
if (prach_sequence_length == 0) {
if (prach_fmt == 0 || prach_fmt == 1 || prach_fmt == 2) {
if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) {
dftlen=73728;
dft73728(prach2,rxsigF[aa],1);
reps++;
}
if (prach_fmt == 1 || prach_fmt == 2) {
if (prachFormat == 1 || prachFormat == 2) {
dft73728(prach2+(2*73728),rxsigF[aa]+(2*73728),1);
reps++;
}
if (prach_fmt == 3) {
if (prachFormat == 3) {
dftlen=18432;
for (int i=0;i<4;i++) dft18432(prach2+(i*2*18432),rxsigF[aa]+(i*2*18432),1);
reps=4;
}
} else {
dftlen=3072;
dft3072(prach2,rxsigF[aa],1);
if (prach_fmt != 7) { //!=C0
dft3072(prach2+6144,rxsigF[aa]+6144,1);
reps++;
}
if (prach_fmt == 1 || prach_fmt == 2 || prach_fmt == 4 || prach_fmt == 5 || prach_fmt == 6 || prach_fmt == 8) {
dft3072(prach2+6144*2,rxsigF[aa]+6144*2,1);
dft3072(prach2+6144*3,rxsigF[aa]+6144*3,1);
reps+=2;
}
if (prach_fmt == 2 || prach_fmt == 5 || prach_fmt == 6) {
dft3072(prach2+6144*4,rxsigF[aa]+6144*4,1);
dft3072(prach2+6144*5,rxsigF[aa]+6144*5,1);
reps+=2;
}
if (prach_fmt == 6) {
for (int i=6;i<12;i++) dft3072(prach2+(6144*i),rxsigF[aa]+(6144*i),1);
reps+=6;
if ((mu==0 &&
(prachStartSymbol == 0 || prachStartSymbol == 7)) ||
(mu==1 && prachStartSymbol == 0)) prach2+=96; // 64 samples @ 122.88 Ms/s in first symbol of each half subframe (15/30 kHz only)
if (mu==0) AssertFatal(1==0,"Shouldn't get here\n");
else if (mu==1) {
dftlen=3072;
dft3072(prach2,rxsigF[aa],1);
if (prachFormat != 7) { //!=C0
dft3072(prach2+6144,rxsigF[aa]+6144,1);
reps++;
}
if (prachFormat == 1 || prachFormat == 2 || prachFormat == 4 || prachFormat == 5 || prachFormat == 6 || prachFormat == 8) {
dft3072(prach2+6144*2,rxsigF[aa]+6144*2,1);
dft3072(prach2+6144*3,rxsigF[aa]+6144*3,1);
reps+=2;
}
if (prachFormat == 2 || prachFormat == 5 || prachFormat == 6) {
dft3072(prach2+6144*4,rxsigF[aa]+6144*4,1);
dft3072(prach2+6144*5,rxsigF[aa]+6144*5,1);
reps+=2;
}
if (prachFormat == 6) {
for (int i=6;i<12;i++) dft3072(prach2+(6144*i),rxsigF[aa]+(6144*i),1);
reps+=6;
}
}
else if (mu==2) AssertFatal(1==0,"Shouldn't get here\n");
else if (mu==3) AssertFatal(1==0,"Shouldn't get here\n");
else if (mu==4) AssertFatal(1==0,"Shouldn't get here\n");
}
}
}
......@@ -724,7 +767,6 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
for (i=0; i<NCS2; i++) {
lev = (int32_t)prach_ifft[(preamble_shift2+i)];
levdB = dB_fixed_times10(lev);
if (levdB>*max_preamble_energy) {
*max_preamble_energy = levdB;
*max_preamble_delay = i; // Note: This has to be normalized to the 30.72 Ms/s sampling rate
......
......@@ -122,6 +122,8 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
void rx_nr_prach_ru(RU_t *ru,
int prach_fmt,
int numRA,
int prachStartSymbol,
int frame,
int subframe);
......
......@@ -41,6 +41,8 @@
#include "T.h"
#define NR_PRACH_DEBUG 1
extern uint16_t NCS_unrestricted_delta_f_RA_125[16];
extern uint16_t NCS_restricted_TypeA_delta_f_RA_125[15];
extern uint16_t NCS_restricted_TypeB_delta_f_RA_125[13];
......@@ -111,7 +113,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe)
#else //normal case (simulation)
prach_start = subframe*(fp->samples_per_slot<<1)-ue->N_TA_offset;
LOG_D(PHY,"[UE %d] prach_start %d, rx_offset %d, hw_timing_advance %d, N_TA_offset %d\n", ue->Mod_id,
LOG_I(PHY,"[UE %d] prach_start %d, rx_offset %d, hw_timing_advance %d, N_TA_offset %d\n", ue->Mod_id,
prach_start,
ue->rx_offset,
ue->hw_timing_advance,
......@@ -222,7 +224,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe)
#ifdef NR_PRACH_DEBUG
if (NCS>0)
LOG_D(PHY,"Generate PRACH for RootSeqIndex %d, Preamble Index %d, PRACH Format %x, prach_ConfigIndex %d, NCS %d (NCS_config %d, N_ZC/NCS %d): Preamble_offset %d, Preamble_shift %d\n",
LOG_I(PHY,"Generate PRACH for RootSeqIndex %d, Preamble Index %d, PRACH Format %x, prach_ConfigIndex %d, NCS %d (NCS_config %d, N_ZC/NCS %d): Preamble_offset %d, Preamble_shift %d\n",
rootSequenceIndex,preamble_index,prach_fmt,prach_ConfigIndex,NCS,Ncs_config,N_ZC/NCS,
preamble_offset,preamble_shift);
......@@ -251,7 +253,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe)
k*=K;
k+=kbar;
LOG_D(PHY,"placing prach in position %d\n",k);
LOG_I(PHY,"placing prach in position %d\n",k);
k*=2;
Xu = (int16_t*)ue->X_u[preamble_offset-first_nonzero_root_idx];
......@@ -427,6 +429,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe)
dftlen=12288;
}
else if (prach_fmt == 0xa1 || prach_fmt == 0xb1 || prach_fmt == 0xc0) {
Ncp+=32; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
prach2 = prach+(Ncp<<1);
idft2048(prachF,prach2,1);
dftlen=2048;
......@@ -440,6 +443,8 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe)
// here we have |Prefix | Prach2048 | Prach2048 (if ! 0xc0) |
}
else if (prach_fmt == 0xa2 || prach_fmt == 0xb2) { // 6x2048
Ncp+=32; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
prach2 = prach+(Ncp<<1);
idft2048(prachF,prach2,1);
dftlen=2048;
// here we have |empty | Prach2048 |
......@@ -452,6 +457,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe)
prach_len = (2048*4)+Ncp;
}
else if (prach_fmt == 0xa3 || prach_fmt == 0xb3) { // 6x2048
Ncp+=32;
prach2 = prach+(Ncp<<1);
idft2048(prachF,prach2,1);
dftlen=2048;
......@@ -467,6 +473,8 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe)
prach_len = (2048*6)+Ncp;
}
else if (prach_fmt == 0xb4) { // 12x2048
Ncp+=32; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
prach2 = prach+(Ncp<<1);
idft2048(prachF,prach2,1);
dftlen=2048;
// here we have |empty | Prach2048 |
......@@ -527,19 +535,23 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe)
prach_len = (9216*4)+Ncp;
}
else if (prach_fmt == 0xa1 || prach_fmt == 0xb1 || prach_fmt == 0xc0) {
Ncp+=24; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
prach2 = prach+(Ncp<<1);
idft1536(prachF,prach2,1);
dftlen=1536;
// here we have |empty | Prach1536 |
if (prach_fmt != 0xc0) {
memmove(prach2+(1536<<1),prach2,(1536<<2));
prach_len = (1536*2)+Ncp;
}
else prach_len = (1536*1)+Ncp;
memmove(prach2+(1536<<1),prach2,(1536<<2));
prach_len = (1536*2)+Ncp;
}
else prach_len = (1536*1)+Ncp;
memmove(prach,prach+(1536<<1),(Ncp<<2));
// here we have |Prefix | Prach1536 | Prach1536 (if ! 0xc0) |
}
else if (prach_fmt == 0xa2 || prach_fmt == 0xb2) { // 6x1536
Ncp+=24; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
prach2 = prach+(Ncp<<1);
idft1536(prachF,prach2,1);
dftlen=1536;
// here we have |empty | Prach1536 |
......@@ -552,6 +564,8 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe)
prach_len = (1536*4)+Ncp;
}
else if (prach_fmt == 0xa3 || prach_fmt == 0xb3) { // 6x1536
Ncp+=24; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
prach2 = prach+(Ncp<<1);
idft1536(prachF,prach2,1);
dftlen=1536;
// here we have |empty | Prach1536 |
......@@ -566,6 +580,8 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe)
prach_len = (1536*6)+Ncp;
}
else if (prach_fmt == 0xb4) { // 12x1536
Ncp+=24; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
prach2 = prach+(Ncp<<1);
idft1536(prachF,prach2,1);
dftlen=1536;
// here we have |empty | Prach1536 |
......@@ -627,6 +643,8 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe)
prach_len = (24576*4)+Ncp;
}
else if (prach_fmt == 0xa1 || prach_fmt == 0xb1 || prach_fmt == 0xc0) {
Ncp+=64; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
prach2 = prach+(Ncp<<1);
idft4096(prachF,prach2,1);
dftlen=4096;
// here we have |empty | Prach4096 |
......@@ -640,6 +658,8 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe)
}
else if (prach_fmt == 0xa2 || prach_fmt == 0xb2) { // 4x4096
Ncp+=64; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
prach2 = prach+(Ncp<<1);
idft4096(prachF,prach2,1);
dftlen=4096;
// here we have |empty | Prach4096 |
......@@ -652,6 +672,8 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe)
prach_len = (4096*4)+Ncp;
}
else if (prach_fmt == 0xa3 || prach_fmt == 0xb3) { // 6x4096
Ncp+=64; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
prach2 = prach+(Ncp<<1);
idft4096(prachF,prach2,1);
dftlen=4096;
// here we have |empty | Prach4096 |
......@@ -666,6 +688,8 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe)
prach_len = (4096*6)+Ncp;
}
else if (prach_fmt == 0xb4) { // 12x4096
Ncp+=64; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
prach2 = prach+(Ncp<<1);
idft4096(prachF,prach2,1);
dftlen=4096;
// here we have |empty | Prach4096 |
......@@ -725,6 +749,8 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe)
prach_len = (18432*4)+Ncp;
}
else if (prach_fmt == 0xa1 || prach_fmt == 0xb1 || prach_fmt == 0xc0) {
Ncp+=48; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
prach2 = prach+(Ncp<<1);
idft3072(prachF,prach2,1);
dftlen=3072;
// here we have |empty | Prach3072 |
......@@ -737,6 +763,8 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe)
// here we have |Prefix | Prach3072 | Prach3072 (if ! 0xc0) |
}
else if (prach_fmt == 0xa3 || prach_fmt == 0xb3) { // 6x3072
Ncp+=48; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
prach2 = prach+(Ncp<<1);
idft3072(prachF,prach2,1);
dftlen=3072;
// here we have |empty | Prach3072 |
......@@ -751,6 +779,8 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe)
prach_len = (3072*6)+Ncp;
}
else if (prach_fmt == 0xa2 || prach_fmt == 0xb2) { // 4x3072
Ncp+=48; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
prach2 = prach+(Ncp<<1);
idft3072(prachF,prach2,1);
dftlen=3072;
// here we have |empty | Prach3072 |
......@@ -763,6 +793,8 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe)
prach_len = (3072*4)+Ncp;
}
else if (prach_fmt == 0xb4) { // 12x3072
Ncp+=48; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
prach2 = prach+(Ncp<<1);
idft3072(prachF,prach2,1);
dftlen=3072;
// here we have |empty | Prach3072 |
......
......@@ -193,6 +193,8 @@ typedef struct {
int frame;
int slot;
int fmt;
int numRA;
int prachStartSymbol;
} RU_PRACH_list_t;
#define NUMBER_OF_NR_RU_PRACH_MAX 8
......
......@@ -212,9 +212,7 @@ void nr_dump_dlsch_SI(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,
#endif
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)
unsigned int gain_table[31] = {100,112,126,141,158,178,200,224,251,282,316,359,398,447,501,562,631,708,794,891,1000,1122,1258,1412,1585,1778,1995,2239,2512,2818,3162};
#endif
int get_tx_amp_prach(int power_dBm, int power_max_dBm, int N_RB_UL){
......@@ -4490,7 +4488,7 @@ uint8_t nr_is_ri_TXOp(PHY_VARS_NR_UE *ue,
void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id, runmode_t runmode) {
int frame_tx = proc->frame_tx, nr_tti_tx = proc->nr_tti_tx, prach_power, tx_amp;
uint16_t preamble_tx = 50, pathloss;
uint16_t /*preamble_tx = 50,*/ pathloss;
uint8_t mod_id = ue->Mod_id;
UE_MODE_t UE_mode = get_nrUE_mode(mod_id, ue->CC_id, gNB_id);
NR_PRACH_RESOURCES_t * prach_resources = ue->prach_resources[gNB_id];
......@@ -4499,7 +4497,7 @@ void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t
ue->generate_nr_prach = 0;
if (ue->mac_enabled == 0){
prach_resources->ra_PreambleIndex = preamble_tx;
// prach_resources->ra_PreambleIndex = preamble_tx;
prach_resources->ra_TDD_map_index = 0;
prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = 10;
prach_resources->ra_RNTI = 0x1234;
......@@ -4593,4 +4591,4 @@ void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t
ue->generate_nr_prach = 0;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_OUT);
}
\ No newline at end of file
}
......@@ -7,3 +7,342 @@ int32_t get_uldl_offset(int nr_bandP) { re
NR_IF_Module_t *NR_IF_Module_init(int Mod_id) {return(NULL);}
int dummy_nr_ue_dl_indication(nr_downlink_indication_t *dl_info) { return(0); }
int dummy_nr_ue_ul_indication(nr_uplink_indication_t *ul_info) { return(0); }
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file ra_procedures.c
* \brief Routines for UE MAC-layer Random Access procedures (TS 38.321, Release 15)
* \author R. Knopp, Navid Nikaein, Guido Casati
* \date 2019
* \version 0.1
* \company Eurecom
* \email: knopp@eurecom.fr navid.nikaein@eurecom.fr, guido.casati@iis.fraunhofer.de
* \note
* \warning
*/
#include "mac.h"
/*
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "PHY_INTERFACE/phy_interface_extern.h"
#include "SCHED_UE/sched_UE.h"
#include "COMMON/mac_rrc_primitives.h"
#include "RRC/LTE/rrc_extern.h"
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
#include "common/utils/LOG/log.h"
#include "UTIL/OPT/opt.h"
#include "OCG.h"
#include "OCG_extern.h"
#include "PHY/LTE_ESTIMATION/lte_estimation.h"*/
/* Tools */
#include "SIMULATION/TOOLS/sim.h" // for taus
/* RRC */
#include "NR_RACH-ConfigCommon.h"
/* PHY */
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
#include "PHY/defs_common.h"
#include "PHY/defs_nr_common.h"
#include "PHY/NR_UE_ESTIMATION/nr_estimation.h"
/* MAC */
#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
#include "NR_MAC_COMMON/nr_mac.h"
#include "LAYER2/NR_MAC_UE/mac_proto.h"
extern int64_t table_6_3_3_2_2_prachConfig_Index [256][9];
extern int64_t table_6_3_3_2_3_prachConfig_Index [256][9];
//extern uint8_t nfapi_mode;
// WIP
// This routine implements Section 5.1.2 (UE Random Access Resource Selection)
// and Section 5.1.3 (Random Access Preamble Transmission) from 3GPP TS 38.321
void nr_get_prach_resources(module_id_t mod_id,
int CC_id,
uint8_t gNB_id,
uint8_t t_id,
uint8_t first_Msg3,
NR_PRACH_RESOURCES_t *prach_resources,
NR_RACH_ConfigDedicated_t * rach_ConfigDedicated){
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon;
// NR_BeamFailureRecoveryConfig_t *beam_failure_recovery_config = &mac->RA_BeamFailureRecoveryConfig; // todo
int messagePowerOffsetGroupB, messageSizeGroupA, PLThreshold, sizeOfRA_PreamblesGroupA, numberOfRA_Preambles, i, deltaPreamble_Msg3;
uint8_t noGroupB = 0, s_id, f_id, ul_carrier_id, msg1_FDM, prach_ConfigIndex, SFN_nbr, Msg3_size;
// NR_RSRP_Range_t rsrp_ThresholdSSB; // todo
///////////////////////////////////////////////////////////
//////////* UE Random Access Resource Selection *//////////
///////////////////////////////////////////////////////////
// todo:
// - switch initialisation cases
// -- RA initiated by beam failure recovery operation (subclause 5.17 TS 38.321)
// --- SSB selection, set prach_resources->ra_PreambleIndex
// -- RA initiated by PDCCH: ra_preamble_index provided by PDCCH && ra_PreambleIndex != 0b000000
// --- set PREAMBLE_INDEX to ra_preamble_index
// --- select the SSB signalled by PDCCH
// -- RA initiated for SI request:
// --- SSB selection, set prach_resources->ra_PreambleIndex
// if (rach_ConfigDedicated) { // This is for network controlled Mobility
// // operation for contention-free RA resources when:
// // - available SSB with SS-RSRP above rsrp-ThresholdSSB: SSB selection
// // - availalbe CSI-RS with CSI-RSRP above rsrp-ThresholdCSI-RS: CSI-RS selection
// prach_resources->ra_PreambleIndex = rach_ConfigDedicated->ra_PreambleIndex;
// return;
// }
//////////* Contention-based RA preamble selection *//////////
// todo:
// - selection of SSB with SS-RSRP above rsrp-ThresholdSSB else select any SSB
// - todo determine next available PRACH occasion
// rsrp_ThresholdSSB = *nr_rach_ConfigCommon->rsrp_ThresholdSSB;
AssertFatal(mac->nr_rach_ConfigCommon != NULL, "[UE %d] FATAL nr_rach_ConfigCommon is NULL !!!\n", mod_id);
nr_rach_ConfigCommon = mac->nr_rach_ConfigCommon;
Msg3_size = mac->RA_Msg3_size;
numberOfRA_Preambles = *nr_rach_ConfigCommon->totalNumberOfRA_Preambles;
if (!nr_rach_ConfigCommon->groupBconfigured) {
noGroupB = 1;
} else {
// RA preambles group B is configured
// - Defining the number of RA preambles in RA Preamble Group A for each SSB */
sizeOfRA_PreamblesGroupA = nr_rach_ConfigCommon->groupBconfigured->numberOfRA_PreamblesGroupA;
switch (nr_rach_ConfigCommon->groupBconfigured->ra_Msg3SizeGroupA){
/* - Threshold to determine the groups of RA preambles */
case 0:
messageSizeGroupA = 56;
break;
case 1:
messageSizeGroupA = 144;
break;
case 2:
messageSizeGroupA = 208;
break;
case 3:
messageSizeGroupA = 256;
break;
case 4:
messageSizeGroupA = 282;
break;
case 5:
messageSizeGroupA = 480;
break;
case 6:
messageSizeGroupA = 640;
break;
case 7:
messageSizeGroupA = 800;
break;
case 8:
messageSizeGroupA = 1000;
break;
case 9:
messageSizeGroupA = 72;
break;
default:
AssertFatal(1 == 0,"Unknown ra_Msg3SizeGroupA %lu\n", nr_rach_ConfigCommon->groupBconfigured->ra_Msg3SizeGroupA);
/* todo cases 10 -15*/
}
/* Power offset for preamble selection in dB */
messagePowerOffsetGroupB = -9999;
switch (nr_rach_ConfigCommon->groupBconfigured->messagePowerOffsetGroupB){
case 0:
messagePowerOffsetGroupB = -9999;
break;
case 1:
messagePowerOffsetGroupB = 0;
break;
case 2:
messagePowerOffsetGroupB = 5;
break;
case 3:
messagePowerOffsetGroupB = 8;
break;
case 4:
messagePowerOffsetGroupB = 10;
break;
case 5:
messagePowerOffsetGroupB = 12;
break;
case 6:
messagePowerOffsetGroupB = 15;
break;
case 7:
messagePowerOffsetGroupB = 18;
break;
default:
AssertFatal(1 == 0,"Unknown messagePowerOffsetGroupB %lu\n", nr_rach_ConfigCommon->groupBconfigured->messagePowerOffsetGroupB);
}
// todo Msg3-DeltaPreamble should be provided from higher layers, otherwise is 0
mac->deltaPreamble_Msg3 = 0;
deltaPreamble_Msg3 = mac->deltaPreamble_Msg3;
}
PLThreshold = prach_resources->RA_PCMAX - nr_rach_ConfigCommon->rach_ConfigGeneric.preambleReceivedTargetPower - deltaPreamble_Msg3 - messagePowerOffsetGroupB;
/* Msg3 has not been transmitted yet */
if (first_Msg3 == 1) {
if (noGroupB == 1) {
// use Group A preamble
prach_resources->ra_PreambleIndex = (taus()) % numberOfRA_Preambles;
mac->RA_usedGroupA = 1;
} else if ((Msg3_size < messageSizeGroupA) && (get_nr_PL(mod_id, CC_id, gNB_id) > PLThreshold)) {
// Group B is configured and RA preamble Group A is used
// - todo add condition on CCCH_sdu_size for initiation by CCCH
prach_resources->ra_PreambleIndex = (taus()) % sizeOfRA_PreamblesGroupA;
mac->RA_usedGroupA = 1;
} else {
// Group B preamble is configured and used
// the first sizeOfRA_PreamblesGroupA RA preambles belong to RA Preambles Group A
// the remaining belong to RA Preambles Group B
prach_resources->ra_PreambleIndex = sizeOfRA_PreamblesGroupA + (taus()) % (numberOfRA_Preambles - sizeOfRA_PreamblesGroupA);
mac->RA_usedGroupA = 0;
}
} else { // Msg3 is being retransmitted
if (mac->RA_usedGroupA == 1 && noGroupB == 1) {
prach_resources->ra_PreambleIndex = (taus()) % numberOfRA_Preambles;
} else if (mac->RA_usedGroupA == 1 && noGroupB == 0){
prach_resources->ra_PreambleIndex = (taus()) % sizeOfRA_PreamblesGroupA;
} else {
prach_resources->ra_PreambleIndex = sizeOfRA_PreamblesGroupA + (taus()) % (numberOfRA_Preambles - sizeOfRA_PreamblesGroupA);
}
}
// todo determine next available PRACH occasion
// - if RA initiated for SI request and ra_AssociationPeriodIndex and si-RequestPeriod are configured
// - else if SSB is selected above
// - else if CSI-RS is selected above
/////////////////////////////////////////////////////////////////////////////
//////////* Random Access Preamble Transmission (5.1.3 TS 38.321) *//////////
/////////////////////////////////////////////////////////////////////////////
// todo:
// - condition on notification of suspending power ramping counter from lower layer (5.1.3 TS 38.321)
// - check if SSB or CSI-RS have not changed since the selection in the last RA Preamble tranmission
// - Extend RA_rnti computation (e.g. f_id selection, ul_carrier_id are hardcoded)
if (mac->RA_PREAMBLE_TRANSMISSION_COUNTER > 1)
mac->RA_PREAMBLE_TRANSMISSION_COUNTER++;
prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = nr_get_Po_NOMINAL_PUSCH(prach_resources, mod_id, CC_id);
// RA-RNTI computation (associated to PRACH occasion in which the RA Preamble is transmitted)
// 1) this does not apply to contention-free RA Preamble for beam failure recovery request
// 2) getting star_symb, SFN_nbr from table 6.3.3.2-3 (TDD and FR1 scenario)
switch (nr_rach_ConfigCommon->rach_ConfigGeneric.msg1_FDM){ // todo this is not used
case 0:
msg1_FDM = 1;
break;
case 1:
msg1_FDM = 2;
break;
case 2:
msg1_FDM = 4;
break;
case 3:
msg1_FDM = 8;
break;
default:
AssertFatal(1 == 0,"Unknown msg1_FDM %lu\n", nr_rach_ConfigCommon->rach_ConfigGeneric.msg1_FDM);
}
prach_ConfigIndex = nr_rach_ConfigCommon->rach_ConfigGeneric.prach_ConfigurationIndex;
// ra_RNTI computation
// - todo: this is for TDD FR1 only
// - ul_carrier_id: UL carrier used for RA preamble transmission, hardcoded for NUL carrier
// - f_id: index of the PRACH occasion in the frequency domain
// - s_id is starting symbol of the PRACH occasion [0...14]
// - t_id is the first slot of the PRACH occasion in a system frame [0...80]
ul_carrier_id = 0; // NUL
f_id = nr_rach_ConfigCommon->rach_ConfigGeneric.msg1_FrequencyStart;
SFN_nbr = table_6_3_3_2_3_prachConfig_Index[prach_ConfigIndex][4];
s_id = table_6_3_3_2_3_prachConfig_Index[prach_ConfigIndex][5];
// Pick the first slot of the PRACH occasion in a system frame
for (i = 0; i < 10; i++){
if (((SFN_nbr & (1 << i)) >> i) == 1){
t_id = 2*i;
break;
}
}
prach_resources->ra_RNTI = 1 + s_id + 14 * t_id + 1120 * f_id + 8960 * ul_carrier_id;
mac->ra_rnti = prach_resources->ra_RNTI;
LOG_D(MAC, "Computed ra_RNTI is %d", prach_resources->ra_RNTI);
}
// TbD: RA_attempt_number not used
void nr_Msg1_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id){
AssertFatal(CC_id == 0, "Transmission on secondary CCs is not supported yet\n");
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
mac->ra_state = WAIT_RAR;
// Start contention resolution timer
mac->RA_attempt_number++;
}
void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id){
AssertFatal(CC_id == 0, "Transmission on secondary CCs is not supported yet\n");
LOG_D(MAC,"[UE %d][RAPROC] Frame %d : Msg3_tx: Starting contention resolution timer\n", mod_id, frameP);
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
// start contention resolution timer
mac->RA_contention_resolution_cnt = 0;
mac->RA_contention_resolution_timer_active = 1;
}
/////////////////////////////////////////////////////////////////////////
///////* Random Access Preamble Initialization (5.1.1 TS 38.321) *///////
/////////////////////////////////////////////////////////////////////////
/// Handling inizialization by PDCCH order, MAC entity or RRC (TS 38.300)
/// Only one RA procedure is ongoing at any point in time in a MAC entity
/// the RA procedure on a SCell shall only be initiated by PDCCH order
// WIP
// todo TS 38.321:
// - check if carrier to use is explicitly signalled then do (1) RA CARRIER SELECTION (SUL, NUL) (2) set PCMAX
// - BWP operation (subclause 5.15 TS 38.321)
// - handle initialization by beam failure recovery
// - handle initialization by handover
// - handle transmission on DCCH using PRACH (during handover, or sending SR for example)
// - take into account MAC CEs in size_sdu (currently hardcoded size to 1 MAC subPDU and 1 padding subheader)
// - fix rrc data req logic
// - retrieve TBS
// - add mac_rrc_nr_data_req_ue, etc ...
// - add the backoff condition here if we have it from a previous RA reponse which failed (i.e. backoff indicator)
......@@ -55,4 +55,15 @@ signed char quantize(double D, double x, unsigned char B) {
return ((char) qxd);
}
int8_t nr_ue_get_SR(module_id_t module_idP, int CC_id, frame_t frameP, uint8_t eNB_id, uint16_t rnti, sub_frame_t subframe) {
AssertFatal(1==0,"Shouldn't be here ...\n");
return 0;
}
int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind) {return(0);}
NR_IF_Module_t *NR_IF_Module_init(int Mod_id){return(NULL);}
int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) { return(0); }
#endif
......@@ -42,11 +42,15 @@
#include "PHY/MODULATION/modulation_UE.h"
#include "PHY/INIT/phy_init.h"
#include "PHY/NR_TRANSPORT/nr_transport.h"
#include "PHY/NR_TRANSPORT/nr_transport_proto_common.h"
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
#include "nr_unitary_defs.h"
#include "OCG_vars.h"
#include <pthread.h>
PHY_VARS_gNB *gNB;
PHY_VARS_NR_UE *UE;
RAN_CONTEXT_t RC;
......@@ -59,27 +63,33 @@ extern uint16_t prach_root_sequence_map0_3[838];
void dump_nr_prach_config(NR_DL_FRAME_PARMS *frame_parms,uint8_t subframe);
uint16_t NB_UE_INST=1;
volatile int oai_exit=0;
void exit_function(const char* file, const char* function, const int line,const char *s) {
const char * msg= s==NULL ? "no comment": s;
printf("Exiting at: %s:%d %s(), %s\n", file, line, function, msg);
exit(-1);
}
int8_t nr_ue_get_SR(module_id_t module_idP, int CC_id, frame_t frameP, uint8_t eNB_id, uint16_t rnti, sub_frame_t subframe) {
AssertFatal(1==0,"Shouldn't be here ...\n");
return 0;
}
int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind) {return(0);}
openair0_config_t openair0_cfg[MAX_CARDS];
uint8_t nfapi_mode=0;
NR_IF_Module_t *NR_IF_Module_init(int Mod_id){return(NULL);}
int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) { return(0); }
void nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
module_id_t mod_id,
int CC_id,
UE_MODE_t UE_mode,
frame_t frame,
uint8_t gNB_id,
int nr_tti_tx) { return;}
void nr_Msg1_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id) { return;}
uint16_t nr_ue_process_rar(module_id_t mod_id,
int CC_id,
frame_t frameP,
uint8_t * dlsch_buffer,
rnti_t * t_crnti,
uint8_t preamble_index,
uint8_t * selected_rar_buffer) { return 0;}
int is_nr_prach_subframe(NR_DL_FRAME_PARMS *fp,uint32_t frame,uint8_t slot) { return(1);}
int get_nr_prach_fmt(int prachConfigIndex,int frame_type,int fr) { return(0xa2); }
int main(int argc, char **argv)
{
......@@ -203,7 +213,7 @@ int main(int argc, char **argv)
break;
default:
msg("Unsupported channel model!\n");
printf("Unsupported channel model!\n");
exit(-1);
}
......@@ -219,13 +229,13 @@ int main(int argc, char **argv)
case 's':
snr0 = atof(optarg);
msg("Setting SNR0 to %f\n",snr0);
printf("Setting SNR0 to %f\n",snr0);
break;
case 'S':
snr1 = atof(optarg);
snr1set=1;
msg("Setting SNR1 to %f\n",snr1);
printf("Setting SNR1 to %f\n",snr1);
break;
case 'p':
......@@ -268,7 +278,7 @@ int main(int argc, char **argv)
if ((transmission_mode!=1) &&
(transmission_mode!=2) &&
(transmission_mode!=6)) {
msg("Unsupported transmission mode %d\n",transmission_mode);
printf("Unsupported transmission mode %d\n",transmission_mode);
exit(-1);
}
......@@ -278,7 +288,7 @@ int main(int argc, char **argv)
n_tx=atoi(optarg);
if ((n_tx==0) || (n_tx>2)) {
msg("Unsupported number of tx antennas %d\n",n_tx);
printf("Unsupported number of tx antennas %d\n",n_tx);
exit(-1);
}
......@@ -288,7 +298,7 @@ int main(int argc, char **argv)
n_rx=atoi(optarg);
if ((n_rx==0) || (n_rx>2)) {
msg("Unsupported number of rx antennas %d\n",n_rx);
printf("Unsupported number of rx antennas %d\n",n_rx);
exit(-1);
}
......@@ -400,10 +410,24 @@ int main(int argc, char **argv)
ru->nb_tx = n_tx;
ru->nb_rx = n_rx;
gNB->gNB_config.carrier_config.num_tx_ant.value=1;
gNB->gNB_config.carrier_config.num_rx_ant.value=1;
gNB->gNB_config.prach_config.num_prach_fd_occasions_list = (nfapi_nr_num_prach_fd_occasions_t *) malloc(gNB->gNB_config.prach_config.num_prach_fd_occasions.value*sizeof(nfapi_nr_num_prach_fd_occasions_t));
gNB->gNB_config.prach_config.num_prach_fd_occasions_list[0].prach_root_sequence_index.value = 1;
gNB->gNB_config.prach_config.num_prach_fd_occasions_list[0].num_root_sequences.value = 16;
gNB->gNB_config.prach_config.prach_sequence_length.value = 1;
gNB->gNB_config.prach_config.num_prach_fd_occasions_list[0].k1.value = 0;
gNB->gNB_config.prach_config.restricted_set_config.value = 0;
gNB->gNB_config.tdd_table.tdd_period.value = 6;
memcpy((void*)&ru->config,(void*)&RC.gNB[0]->gNB_config,sizeof(ru->config));
RC.nb_nr_L1_inst=1;
phy_init_nr_gNB(gNB,0,0);
nr_phy_init_RU(ru);
set_tdd_config_nr(&gNB->gNB_config, 5000,
set_tdd_config_nr(&gNB->gNB_config, 1,
7, 6,
2, 4);
......@@ -481,21 +505,9 @@ int main(int argc, char **argv)
gNB->common_vars.rxdata = ru->common.rxdata;
compute_nr_prach_seq(gNB->frame_parms.prach_config_common.rootSequenceIndex,
gNB->frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex,
gNB->frame_parms.prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig,
gNB->frame_parms.prach_config_common.prach_ConfigInfo.highSpeedFlag,
gNB->frame_parms.frame_type,
gNB->frame_parms.freq_range,
gNB->X_u);
compute_nr_prach_seq(&gNB->gNB_config,0,gNB->X_u);
compute_nr_prach_seq(UE->frame_parms.prach_config_common.rootSequenceIndex,
UE->frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex,
UE->frame_parms.prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig,
UE->frame_parms.prach_config_common.prach_ConfigInfo.highSpeedFlag,
UE->frame_parms.frame_type,
UE->frame_parms.freq_range,
UE->X_u);
compute_nr_prach_seq(&gNB->gNB_config,0,UE->X_u);
......@@ -517,6 +529,7 @@ int main(int argc, char **argv)
subframe); */ //commented for testing purpose
UE_nr_rxtx_proc_t proc={0};
proc.frame_tx=0;proc.nr_tti_tx=subframe;
nr_ue_prach_procedures(UE,&proc,0,0);
/* tx_lev_dB not used later, no need to set */
......@@ -526,7 +539,7 @@ int main(int argc, char **argv)
//LOG_M("txsig1.m","txs1", txdata[1],FRAME_LENGTH_COMPLEX_SAMPLES,1,1);
// multipath channel
dump_nr_prach_config(&gNB->frame_parms,subframe);
// dump_nr_prach_config(&gNB->frame_parms,subframe);
for (i=0; i<frame_parms->samples_per_slot<<1; i++) {
for (aa=0; aa<1; aa++) {
......@@ -589,18 +602,26 @@ int main(int argc, char **argv)
}
uint16_t preamble_rx;
rx_nr_prach_ru(ru,
1,
0,
subframe);
0,
0,
subframe<<1);
gNB->prach_vars.rxsigF = ru->prach_rxsigF;
nfapi_nr_prach_pdu_t prach_pdu;
prach_pdu.num_cs = 34;
prach_pdu.prach_format = 1; // A2
rx_nr_prach(gNB,
&prach_pdu,
0,
subframe,
subframe<<1,
&preamble_rx,
&preamble_energy,
&preamble_delay);
printf("preamble_rx %d\n", preamble_rx);
if (preamble_rx!=preamble_tx)
if (preamble_rx!=preamble_tx)
prach_errors++;
else {
delay_avg += (double)preamble_delay;
......
......@@ -600,4 +600,4 @@ void nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
}
prach_resources = NULL;
return;
}
\ No newline at end of file
}
......@@ -134,4 +134,4 @@ uint16_t nr_ue_process_rar(module_id_t mod_id,
memcpy((void *) (selected_rar_buffer + 1), (void *) rar, sizeof(NR_MAC_RAR));
return ta_command;
}
\ No newline at end of file
}
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