diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 19284a3d72..2e0dde6c67 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -34,6 +34,7 @@ #include "LAYER2/nr_pdcp/nr_pdcp_entity.h" #include "openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h" #include "PHY/NR_REFSIG/refsig_defs_ue.h" +#include "radio/COMMON/common_lib.h" /* * NR SLOT PROCESSING SEQUENCE @@ -602,6 +603,61 @@ static void UE_synch(void *arg) { } } +static void RU_write(nr_rxtx_thread_data_t *rxtxD) { + + PHY_VARS_NR_UE *UE = rxtxD->UE; + UE_nr_rxtx_proc_t *proc = &rxtxD->proc; + + void *txp[NB_ANTENNAS_TX]; + for (int i=0; iframe_parms.nb_antennas_tx; i++) + txp[i] = (void *)&UE->common_vars.txdata[i][UE->frame_parms.get_samples_slot_timestamp( + proc->nr_slot_tx, &UE->frame_parms, 0)]; + + radio_tx_flag_t flags = Invalid; + + NR_UE_MAC_INST_t *mac = get_mac_inst(0); + + if (openair0_cfg[0].duplex_mode == duplex_mode_TDD && !get_softmodem_params()->continuous_tx) { + + uint8_t tdd_period = mac->phy_config.config_req.tdd_table.tdd_period_in_slots; + int nrofUplinkSlots, nrofUplinkSymbols; + if (mac->scc) { + nrofUplinkSlots = mac->scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots; + nrofUplinkSymbols = mac->scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols; + } + else { + nrofUplinkSlots = mac->scc_SIB->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots; + nrofUplinkSymbols = mac->scc_SIB->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols; + } + + int slot_tx_usrp = proc->nr_slot_tx; + uint8_t num_UL_slots = nrofUplinkSlots + (nrofUplinkSymbols != 0); + uint8_t first_tx_slot = tdd_period - num_UL_slots; + + if (slot_tx_usrp % tdd_period == first_tx_slot) + flags = StartOfBurst; + else if (slot_tx_usrp % tdd_period == first_tx_slot + num_UL_slots - 1) + flags = EndOfBurst; + else if (slot_tx_usrp % tdd_period > first_tx_slot) + flags = MiddleOfBurst; + } else { + flags = MiddleOfBurst; + } + + if (flags || IS_SOFTMODEM_RFSIM) + AssertFatal(rxtxD->writeBlockSize == + UE->rfdevice.trx_write_func(&UE->rfdevice, + proc->timestamp_tx, + txp, + rxtxD->writeBlockSize, + UE->frame_parms.nb_antennas_tx, + flags),""); + + for (int i=0; iframe_parms.nb_antennas_tx; i++) + memset(txp[i], 0, rxtxD->writeBlockSize); + +} + void processSlotTX(void *arg) { nr_rxtx_thread_data_t *rxtxD = (nr_rxtx_thread_data_t *) arg; @@ -635,6 +691,8 @@ void processSlotTX(void *arg) { phy_procedures_nrUE_TX(UE, proc, proc->gNB_id, &phy_data); } + + RU_write(rxtxD); } void UE_processing(nr_rxtx_thread_data_t *rxtxD) { @@ -783,7 +841,7 @@ void *UE_thread(void *arg) { PHY_VARS_NR_UE *UE = (PHY_VARS_NR_UE *) arg; // int tx_enabled = 0; openair0_timestamp timestamp, writeTimestamp; - void *rxp[NB_ANTENNAS_RX], *txp[NB_ANTENNAS_TX]; + void *rxp[NB_ANTENNAS_RX]; int start_rx_stream = 0; fapi_nr_config_request_t *cfg = &UE->nrUE_config; AssertFatal(0== openair0_device_load(&(UE->rfdevice), &openair0_cfg[0]), ""); @@ -795,11 +853,14 @@ void *UE_thread(void *arg) { notifiedFIFO_t nf; initNotifiedFIFO(&nf); + notifiedFIFO_t txFifo; + initNotifiedFIFO(&txFifo); + notifiedFIFO_t freeBlocks; initNotifiedFIFO_nothreadSafe(&freeBlocks); - NR_UE_MAC_INST_t *mac = get_mac_inst(0); int timing_advance = UE->timing_advance; + NR_UE_MAC_INST_t *mac = get_mac_inst(0); bool syncRunning=false; const int nb_slot_frame = UE->frame_parms.slots_per_frame; @@ -870,7 +931,6 @@ void *UE_thread(void *arg) { int slot_nr = absolute_slot % nb_slot_frame; nr_rxtx_thread_data_t curMsg = {0}; - initNotifiedFIFO(&curMsg.txFifo); curMsg.UE=UE; // update thread index for received subframe curMsg.proc.CC_id = UE->CC_id; @@ -897,20 +957,16 @@ void *UE_thread(void *arg) { rxp[i] = (void *)&UE->common_vars.rxdata[i][firstSymSamp+ UE->frame_parms.get_samples_slot_timestamp(slot_nr,&UE->frame_parms,0)]; - for (int i=0; iframe_parms.nb_antennas_tx; i++) - txp[i] = (void *)&UE->common_vars.txdata[i][UE->frame_parms.get_samples_slot_timestamp( - ((slot_nr + DURATION_RX_TO_TX - NR_RX_NB_TH)%nb_slot_frame),&UE->frame_parms,0)]; - int readBlockSize, writeBlockSize; if (slot_nr<(nb_slot_frame - 1)) { readBlockSize=get_readBlockSize(slot_nr, &UE->frame_parms); - writeBlockSize=UE->frame_parms.get_samples_per_slot((slot_nr + DURATION_RX_TO_TX - NR_RX_NB_TH) % nb_slot_frame, &UE->frame_parms); + writeBlockSize=UE->frame_parms.get_samples_per_slot((slot_nr + DURATION_RX_TO_TX) % nb_slot_frame, &UE->frame_parms); } else { UE->rx_offset_diff = computeSamplesShift(UE); readBlockSize=get_readBlockSize(slot_nr, &UE->frame_parms) - UE->rx_offset_diff; - writeBlockSize=UE->frame_parms.get_samples_per_slot((slot_nr + DURATION_RX_TO_TX - NR_RX_NB_TH) % nb_slot_frame, &UE->frame_parms)- UE->rx_offset_diff; + writeBlockSize=UE->frame_parms.get_samples_per_slot((slot_nr + DURATION_RX_TO_TX) % nb_slot_frame, &UE->frame_parms)- UE->rx_offset_diff; } AssertFatal(readBlockSize == @@ -936,28 +992,30 @@ void *UE_thread(void *arg) { LOG_E(PHY,"can't compensate: diff =%d\n", first_symbols); } - curMsg.proc.timestamp_tx = timestamp+ - UE->frame_parms.get_samples_slot_timestamp(slot_nr,&UE->frame_parms,DURATION_RX_TO_TX) - - firstSymSamp; + // use previous timing_advance value to compute writeTimestamp + writeTimestamp = timestamp+ + UE->frame_parms.get_samples_slot_timestamp(slot_nr,&UE->frame_parms,DURATION_RX_TO_TX) + - firstSymSamp - openair0_cfg[0].tx_sample_advance - + UE->N_TA_offset - timing_advance; + + // but use current UE->timing_advance value to compute writeBlockSize + if (UE->timing_advance != timing_advance) { + writeBlockSize -= UE->timing_advance - timing_advance; + timing_advance = UE->timing_advance; + } // Start TX slot processing here. It runs in parallel with RX slot processing - notifiedFIFO_elt_t *newElt = newNotifiedFIFO_elt(sizeof(nr_rxtx_thread_data_t), curMsg.proc.nr_slot_tx, &curMsg.txFifo, processSlotTX); + notifiedFIFO_elt_t *newElt = newNotifiedFIFO_elt(sizeof(nr_rxtx_thread_data_t), curMsg.proc.nr_slot_tx, &txFifo, processSlotTX); nr_rxtx_thread_data_t *curMsgTx = (nr_rxtx_thread_data_t *) NotifiedFifoData(newElt); curMsgTx->proc = curMsg.proc; + curMsgTx->writeBlockSize = writeBlockSize; + curMsgTx->proc.timestamp_tx = writeTimestamp; curMsgTx->UE = UE; pushTpool(&(get_nrUE_params()->Tpool), newElt); // RX slot processing UE_processing(&curMsg); - // Wait for PUSCH processing to finish - notifiedFIFO_elt_t *res; - res = pullTpool(&curMsg.txFifo, &(get_nrUE_params()->Tpool)); - if (res == NULL) - LOG_E(PHY, "Tpool has been aborted\n"); - else - delNotifiedFIFO_elt(res); - if (curMsg.proc.decoded_frame_rx != -1) decoded_frame_rx=(((mac->mib->systemFrameNumber.buf[0] >> mac->mib->systemFrameNumber.bits_unused)<<4) | curMsg.proc.decoded_frame_rx); else @@ -967,59 +1025,13 @@ void *UE_thread(void *arg) { LOG_E(PHY,"Decoded frame index (%d) is not compatible with current context (%d), UE should go back to synch mode\n", decoded_frame_rx, curMsg.proc.frame_rx); - // use previous timing_advance value to compute writeTimestamp - writeTimestamp = timestamp+ - UE->frame_parms.get_samples_slot_timestamp(slot_nr,&UE->frame_parms,DURATION_RX_TO_TX - - NR_RX_NB_TH) - firstSymSamp - openair0_cfg[0].tx_sample_advance - - UE->N_TA_offset - timing_advance; - - // but use current UE->timing_advance value to compute writeBlockSize - if (UE->timing_advance != timing_advance) { - writeBlockSize -= UE->timing_advance - timing_advance; - timing_advance = UE->timing_advance; - } - - int flags = 0; - - if (openair0_cfg[0].duplex_mode == duplex_mode_TDD && !get_softmodem_params()->continuous_tx) { - - uint8_t tdd_period = mac->phy_config.config_req.tdd_table.tdd_period_in_slots; - int nrofUplinkSlots, nrofUplinkSymbols; - if (mac->scc) { - nrofUplinkSlots = mac->scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots; - nrofUplinkSymbols = mac->scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols; - } - else { - nrofUplinkSlots = mac->scc_SIB->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots; - nrofUplinkSymbols = mac->scc_SIB->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols; - } - - int slot_tx_usrp = slot_nr + DURATION_RX_TO_TX - NR_RX_NB_TH; - uint8_t num_UL_slots = nrofUplinkSlots + (nrofUplinkSymbols != 0); - uint8_t first_tx_slot = tdd_period - num_UL_slots; - - if (slot_tx_usrp % tdd_period == first_tx_slot) - flags = 2; - else if (slot_tx_usrp % tdd_period == first_tx_slot + num_UL_slots - 1) - flags = 3; - else if (slot_tx_usrp % tdd_period > first_tx_slot) - flags = 1; - } else { - flags = 1; - } - - if (flags || IS_SOFTMODEM_RFSIM) - AssertFatal(writeBlockSize == - UE->rfdevice.trx_write_func(&UE->rfdevice, - writeTimestamp, - txp, - writeBlockSize, - UE->frame_parms.nb_antennas_tx, - flags),""); - - for (int i=0; iframe_parms.nb_antennas_tx; i++) - memset(txp[i], 0, writeBlockSize); - + // Wait for TX slot processing to finish + notifiedFIFO_elt_t *res; + res = pullTpool(&txFifo, &(get_nrUE_params()->Tpool)); + if (res == NULL) + LOG_E(PHY, "Tpool has been aborted\n"); + else + delNotifiedFIFO_elt(res); } // while !oai_exit return NULL; diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index 9c2e20a6e5..2b96f1582c 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -768,8 +768,8 @@ typedef struct nr_rxtx_thread_data_s { UE_nr_rxtx_proc_t proc; PHY_VARS_NR_UE *UE; NR_UE_SCHED_MODE_t ue_sched_mode; - notifiedFIFO_t txFifo; -} nr_rxtx_thread_data_t; + int writeBlockSize; +} nr_rxtx_thread_data_t; typedef struct LDPCDecode_ue_s { PHY_VARS_NR_UE *phy_vars_ue; diff --git a/openair1/PHY/impl_defs_top.h b/openair1/PHY/impl_defs_top.h index 35a965567f..e082db54fb 100644 --- a/openair1/PHY/impl_defs_top.h +++ b/openair1/PHY/impl_defs_top.h @@ -269,9 +269,7 @@ /* FFS_NR_TODO it defines ue capability which is the number of slots */ /* - between reception of pdsch and tarnsmission of its acknowlegment */ /* - between reception of un uplink grant and its related transmission */ -/* - FIXME temprarily set to 5 to avoid timing issues at OAI UE in rfsimulator */ -/* - issues caused by no rendez-vous point between TX and RX in the OAI UE */ -#define NR_UE_CAPABILITY_SLOT_RX_TO_TX (5) +#define NR_UE_CAPABILITY_SLOT_RX_TO_TX (4) #ifndef NO_RAT_NR #define DURATION_RX_TO_TX (NR_UE_CAPABILITY_SLOT_RX_TO_TX) /* for NR this will certainly depends to such UE capability which is not yet defined */ diff --git a/radio/COMMON/common_lib.h b/radio/COMMON/common_lib.h index 368e8e9ac5..3733914ef4 100644 --- a/radio/COMMON/common_lib.h +++ b/radio/COMMON/common_lib.h @@ -150,6 +150,14 @@ typedef enum { gpsdo=2 } clock_source_t; +/*! \brief Radio Tx burst flags */ +typedef enum { + Invalid = 0, + MiddleOfBurst, + StartOfBurst, + EndOfBurst +} radio_tx_flag_t; + /*! \brief Structure used for initializing UDP read threads */ typedef struct { openair0_device *device;